在Web Forms專案上整合新技術,打造現代化網站

作者:陳傳興 (Bruce, 微軟最有價值專家)

早期,當我們談論ASP.NET時,絕大部分的開發者都很清楚且明白我們是在討論使用「伺服器控制項」的WebForms網頁開發技術。2013年開始,ASP.NET開發團隊喊出OneASP.NET架構與實作,在One ASP.NET架構下,ASP.NET不再是網站開發技術?,而是一種通用的底層運作核心,在此核心上提供各種開發技術,提供的網站開發技術有Web Forms、Web Pages、Single Page Apps與MVC(下一代的 MVC 6 = Web Pages + MVC + Web API),提供的服務開發技術有Web API與SignalR。


▲圖表 1 One ASP.NET架構

在 One ASP.NET 架構下應該正確稱呼使用「伺服器控制項」的網頁開發技術為 Web Forms。ASP.NET 開發團隊由 One ASP.NET 與 .NET Framework 4.5 開始,為了讓 Web Forms 也能擁有開發現代化網站的能力,開始專注提供下一代的開發技術與開發平台。

►關閉萬惡的 ViewState

我們都知道,HTTP 是一種無狀態(stateless)的協定,而過去,Web Forms使用了一種特別的機制來保存網頁的狀態,這種機制稱ViewState。ViewState就像神奇魔法讓頁面在與伺服器往返之間(Post Back)能保有頁面狀態。當然,ViewState有優點,也有缺點。


▲圖表 2 ViewState儲存資料庫資料

優點是: ViewState 是存在於 <form> 元素裡的隱藏欄位,並無cookie之類儲存方式的限制。可以將資料庫取出的資料放入ViewState裡,如此一來PostBack時便不需要重讀資料庫。

缺點是:加密的資料存儲在隱藏欄位會使網頁變大,若開發人員因為沒有注意,而在ViewState放入大量的資料,將會造成載入速度變慢。


▲圖表 3 ViewState載入資料庫的頁面數據

✧註:圖表 3在ViewState儲存Northwind的Products資料表。


▲圖表 4 不使用ViewState的頁面數據

來源

資料量

圖表3

25.06 KB

圖表4

9.91 KB

頁面大小減少60%。雖然已經不使用ViewState儲存資料,但預設ViewState依然在運作當中。

Web Forms從.NET Framework 4.5開始,有越來越多的伺服器控制項不需要使用(或依賴) ViewState。我們可以很容易的關閉ViewState的使用,在頁面宣告加入EnableViewState="false"

 <%@ Page EnableViewState="false" %>


▲圖表 5 停用ViewState

頁面由9.91 KB又縮小至6.15 KB,也縮減37%的大小。

如果要整個專案停用ViewState,可以到web.config進行調整:

 <system.web>
  <pages enableViewState="false">
</system.web>

大小是其次,重點在於,現在沒有了ViewState,我們的Web Forms網站依然正常運作且反應更快。

►還在用 Data Source Controls?


▲圖表 6 GridView與SqlDataSouce

過去在使用伺服器控制項(GridView、FormView、ListView…等)時大多會配合著使用Data-Source-Controls(SqlDataSource、ObjectDataSouce…等),但使用Data Source controls會有幾個問題:

  • 難以測試。
  • 難以驗證。
  • 在ASPX檔案中含有大量的T-SQL語法與描述。
 <asp:SqlDataSource ID="gridDS" runat="server"
  ConnectionString="<%$ ConnectionStrings:Northwind %>"
  DeleteCommand="DELETE FROM [Products] WHERE [ProductID] = @ProductID"
  InsertCommand="INSERT INTO [Products] ([ProductName], [SupplierID], [CategoryID], [QuantityPerUnit], [UnitPrice], [UnitsInStock], [UnitsOnOrder], [ReorderLevel], [Discontinued]) VALUES (@ProductName, @SupplierID, @CategoryID, @QuantityPerUnit, @UnitPrice, @UnitsInStock, @UnitsOnOrder, @ReorderLevel,
@Discontinued)"
  SelectCommand="SELECT * FROM [Products]"
  UpdateCommand="UPDATE [Products] SET [ProductName] = @ProductName,
[SupplierID] = @SupplierID, [CategoryID] = @CategoryID, [QuantityPerUnit] =
@QuantityPerUnit, [UnitPrice] = @UnitPrice, [UnitsInStock] = @UnitsInStock,
[UnitsOnOrder] = @UnitsOnOrder, [ReorderLevel] = @ReorderLevel, [Discontinued]
= @Discontinued WHERE [ProductID] = @ProductID">
   
  <DeleteParameters>
    <asp:Parameter Name="ProductID" Type="Int32" />
  </DeleteParameters>

  <InsertParameters>
    <asp:Parameter Name="ProductName" Type="String" />
    <asp:Parameter Name="SupplierID" Type="Int32" />
    <asp:Parameter Name="CategoryID" Type="Int32" />
    <asp:Parameter Name="QuantityPerUnit" Type="String" />
    <asp:Parameter Name="UnitPrice" Type="Decimal" />
    <asp:Parameter Name="UnitsInStock" Type="Int16" />
    <asp:Parameter Name="UnitsOnOrder" Type="Int16" />
    <asp:Parameter Name="ReorderLevel" Type="Int16" />
    <asp:Parameter Name="Discontinued" Type="Boolean" />
  </InsertParameters>
  
  <UpdateParameters>
    <asp:Parameter Name="ProductName" Type="String" />
    <asp:Parameter Name="SupplierID" Type="Int32" />
    <asp:Parameter Name="CategoryID" Type="Int32" />
    <asp:Parameter Name="QuantityPerUnit" Type="String" />
    <asp:Parameter Name="UnitPrice" Type="Decimal" />
    <asp:Parameter Name="UnitsInStock" Type="Int16" />
    <asp:Parameter Name="UnitsOnOrder" Type="Int16" />
    <asp:Parameter Name="ReorderLevel" Type="Int16" />
    <asp:Parameter Name="Discontinued" Type="Boolean" />
    <asp:Parameter Name="ProductID" Type="Int32" />
  </UpdateParameters>
</asp:SqlDataSource>

這是Northwind資料庫Products資料表經由SqlDataSource所產生的程式碼,一般簡單需求,控制項與Data Source都是很不錯的解決方案。但需求慢慢趨向複雜,舉例來說,當我們有大量客製化T-SQL需求,例如Join Table,以前的便利就會變成現在的不便。

開發現代化網站有個重要的觀念:關注點分離(Separation_of_concerns,SoC)。舉例來說,Web_Forms的頁面基本上都是由二支程式組成,Default.aspx與Default.aspx.cs(CodeBehind),那麼我們應盡量讓每一支程式只負責一種工作,Default.aspx負責頁面的呈現,Dafault.aspx.cs負責DAL(Data Access Layer)或BLL(Business Logic Layer)的工作。但使用Data Source Controls會使得這樣的分工難以實作。

Web Forms在.NET_Framework_4.5由ASP.NET MVC框架學習一個非常好用的機制稱為「Model Binding」,Web Forms經由Model Binding可以將原本依賴Data Source Controls的功能,轉而直接呼叫開發好的DAL或BLL的程式模組。

在以下範例中,使用Visual-Studio-2013-Update-2與Entity-Framework-6.1經由Code-First產生Northwind的POCO類別,並且撰寫以下Repository類別:

 public class ProductRepository
{
  private Northwind db;

  public ProductRepository()
  {
    this.db = new Northwind();
  }

  public IQueryable Get()
  {
    return db.Products;
  }

  public void Insert(Product newProduct)
  {
    db.Products.Add(newProduct);
  }

  public void Update(Product product)
  {
    db.Products.Attach(product);
  }

  public void Remove(int id)
  {
    db.Products.Remove(db.Products.Find(id));
  }

  public void Save()
  {
    db.SaveChanges();
  }
}

在伺服器控制項,如GridView,DetailsView,ListView與FormView等為Model Binding提供的新屬性:

  • ☛SelectMethod
  • ☛UpdateMethod
  • ☛DeleteMethod
  • ☛InsertMethod

Default.aspx

 <asp:GridView ID="grid" runat="server" 
  DataKeyNames="ProductID"
  SelectMethod="Get" 
  OnCallingDataMethods="grid_OnCallingDataMethods">
</asp:GridView>

Defualt.aspx.cs

 protected void
grid_OnCallingDataMethods(object sender, CallingDataMethodsEventArgs e)
{
  e.DataMethodsObject = new Models.ProductRepository();
}

就這樣。有了Model Binding之後,Default.aspx專心在呈現工作,不再需要含有大量後端程式的Data Source Controls,原先Data-Source-Controls的後端程式碼可轉為模組化的DAL或BLL,除了可重覆使用之外,維護也方便。

►Bootstrap 3


▲圖表 7 GridView輸出預設效果

在視覺設計這部分,一直是程式設計師的一大挑戰,而且近年行動設備的流行,對於Web-Forms程式設計師更是一大難關,各種伺服器控制項本身並不容易進行UI設計。Visual-Studio-2013開發範本中全面導入Bootstrap-3框架(https://getbootstrap.com/),讓開發人員用最少的力氣也能讓控制項產出的UI擁有專業美工的效果。

圖表7是GridView預設輸出樣式,GridView之類的控制項可以透過CssClass 屬性指定CSS類別來套用即有的CSS類別,例如套用Bootstrap
Css Table類別(https://getbootstrap.com/css/#tables):

▲圖表 8 CssClass=”table” Bootstrap效果


▲圖表 9 CssClass=” table table-striped” Bootstrap效果

引用Bootstrap的另一個好處是12欄網格的設計與RWD(Responsive Web Design)效果取得的立即性。例如,使用行動設備瀏覽預設Web Forms範本根目錄的Defualt.aspx。

▲圖表 10 Nokia 920瀏覽效果

頁面會隨著瀏覽設備的大小自動變更介面的配置。

►肥大的前端框架

前端技術近年來大爆發,各種優秀前端框架孕育而生:jQuery、jQuery UI、KendoUI、Modernizr、Bootstrap、Responsive、Knockout、AngularJS、RequireJS等等。但不管是CSS Framework或JavaScript Framework,雖然帶來強大的功能也不斷加大網頁的大小。大量使用各種前端框架頁面,還有一個問題,那就是不斷增加HTTP要求(HTTP Request)數量。

當FriendlyUrls偵測到要求是來自行動設備時,會自動採用同一支程式的Mobile版本。如圖12,Site.Master是正常版本,當有個要求來自行動設備,就會採用Site.Mobile.Master;ASPX應用程式也是相同原理,例如Default.aspx,我們可以設計Default.Mobile.aspx提供給行動設備使用。

一般:Site.Master

行動:Site.Mobile.Master

 

一般:Default.aspx

行動:Default.Mobile.aspx

 

►上吧,HTML5隊長

HTML5協定已經是未來網站發展確定的方向,Visual Studio 2013對於HTML5的支援度相當完整,Web Forms也以此為基礎進行改良,TextBox控制項提供TextMode屬性讓Web Forms開發者非常簡單就能選用各種HTML5表單屬性:

 <div>
  Color:
  <asp:TextBox runat="server" TextMode="Color"></asp:TextBox>
  <br />
  Date:
  <asp:TextBox runat="server" TextMode="Date"></asp:TextBox>
  <br />
  DateTime:
  <asp:TextBox runat="server" TextMode="DateTime"></asp:TextBox>
  <br />
  DateTimeLocal:
  <asp:TextBox runat="server" TextMode="DateTimeLocal"></asp:TextBox>
  <br />
  Email:
  <asp:TextBox runat="server" TextMode="Email"></asp:TextBox>
  <br />
  Month:
  <asp:TextBox runat="server" TextMode="Month"></asp:TextBox>
  <br />
  Multiline:
  <asp:TextBox runat="server" TextMode="MultiLine"></asp:TextBox>
  <br />
  Number:
  <asp:TextBox runat="server" TextMode="Number"></asp:TextBox>
  <br />
  Password:
  <asp:TextBox runat="server" TextMode="Password"></asp:TextBox>
  <br />
  Phone:
  <asp:TextBox runat="server" TextMode="Phone"></asp:TextBox>
  <br />
  Range:
  <asp:TextBox runat="server" TextMode="Range"></asp:TextBox>
  <br />
  Search:
  <asp:TextBox runat="server" TextMode="Search"></asp:TextBox>
  <br />
  SingleLine:
  <asp:TextBox runat="server" TextMode="SingleLine"></asp:TextBox>
  <br />
  Time:
  <asp:TextBox runat="server" TextMode="Time"></asp:TextBox>
  <br />
  Url:
  <asp:TextBox runat="server" TextMode="Url"></asp:TextBox>
  <br />
  Week:
  <asp:TextBox runat="server" TextMode="Week"></asp:TextBox>
  <br />
</div>

註:呈現與各種效果依瀏覽器與瀏覽器版本有所不同。

另外強烈推薦安裝Visual Studio 2013的Web Essentials擴充套件,它可以讓我們在開發各種HTML5、CSS3、JavaScript時可以如虎添翼。

註:Web Essentials 2013 RTM now available

►結語

Web Forms經過十多年的淬煉已經有非常良好的基礎,但也有”歷史包袱”,但ASP.NET開發團隊並不以此為藉口,反而努力找出方法為了讓Web Forms開發技術也能具備現代化網站開發能力,其中像是不再依賴ViewState的控制項更是一大突破。

另一方面,ASP.NET MVC框架在網站開發技術上獲得的成功,讓ASP.NET開發團隊思考向ASP.NET MVC借用其成功經驗與技術,將ASP.NET MVC優良的技術導入Web Forms開發技術之內,整合Model Binding、Bundling and Minification、ASP.NET Routing等技術的Web Forms,開發現代化網站,No problem!:D

 

----------------------------------------------------------------------------------------------------------------------------

如何訂閱MSDN電子報?

請登入您的LiveID之後,勾選 台灣微軟 MSDN 程式開發人員電子報

登入請由此:https://aka.ms/newsletter-signup

---------------------------------------------------------------------------------------------