2011年2月17日 星期四

ASP.NET Web Forms 4.0的革新(上)

前言:
我知道對很多台灣的開發團隊來說,ASP.NET Web Forms依舊是開發人員的最愛,Web Forms技術陪伴我們走過了將近10個年頭,在Web Forms技術下我們累積了許多的經驗和資源,相較於MVCAJAX、或是還讓人有點搞不清楚的Dynamic Data技術,Web Forms顯然和藹可親多了,面對VS2010的上市,Web Forms也並非完全沒有革新,在本期的這一篇介紹當中,我們將帶領大夥一同來看看,ASP.NET 4.0當中的Web Forms技術

 

面對快速變革的新技術

 

        一如預期的,微軟最新一代的開發工具Visual Studio 201020104月份準時的推出了,對於這個世代的開發人員來說,Web應用程式幾乎已經是開發技術的標準。現在再也沒有人質疑Internet存在的價值,沒有人懷疑應用程式執行在網際網路上的這個形式是否合宜,網路泡沫化早就被我們拋在腦後,如今甚至仰賴Internet的雲端技術開始被大家視為理所當然的趨勢。不僅如此,4G WiMax技術也準備開始初試啼聲磨刀霍霍,而象徵著.NET開發技術成熟穩健的4.0版本,伴隨著Visual Studio 2010,在這個時刻悄然問市

        而這一刻,各位所看到的ASP.NET 4.0,就是微軟集Web應用程式開發技術之大成於一身,所推出的解決方案。在本期與接下來的幾篇文章當中,我們將帶領讀者鳥瞰ASP.NET 4.0技術,以及針對這些技術所帶來的革新與可能性。

更完整的Web Forms技術

 

        ASP.NET誕生到現在已經超過8個年頭,我還有些許印象在2002ASP.NET推出時,ASP開發人員的懷疑與心中的不確定感。如今,在微軟開發社群中,幾乎已經沒有人再質疑ASP.NET開發技術的重要程度,以及取代ASP的必然性。這接近10年的淬煉,讓ASP.NET Web Forms各方面均已經相當成熟而穩定,如今開發人員面對的只是如何更妥善的將其應用到日常的開發工作當中。

        為了更體貼開發人員的需求,ASP.NET Web Forms在這次的改版中也有不少在功能上的增強,當您取得Visual Studio 2010之後,映入眼簾的,是更豐富的專案範本:
        您可能會發現除了我們已經很熟悉的Web應用程式之外,多了MVC 2Dynamic Data應用程式等新增的專案範本。

        將來我們再為各位介紹MVC或是Dynamic Data專案,我們先專注在過去我們已經很熟悉的ASP.NET Web Forms範本上,您會發現有一個『空白Web應用程式』,和過去不同,您會看到透過這個範本建立出來的專案乾淨到不行:
        這次微軟將大夥過去困擾已久的Web.Config大幅簡化,並且把主要的部分放入了machine.config中,而專案中的Web.Config則可以直接繼承使用。

        同時您會發現其中的targetFramework="4.0",表示著該專案是透過.NET 4.0來開發,這邊不得不提Visual Studio 2010當中的多定向支持(Multi-Targeting Support),在Visual Studio 2010當中Multi-Targeting有相當幅度的改良。

        您會發現當您將同一個專案,選擇了不同的.NET Framework支持版本之後,針對同一個控制項或物件,不管是屬性視窗或是Visual Studio 2010當中的intellisense都會跟著調整,並提供正確的選擇。這對開發人員來說確實相當方便,下圖是同一個專案在選擇了不同的編譯對象後,intellisense隨即跟著改變:
        因為從2.04.0的版本更迭過程中,在NameSpaceObject Model上已經累積了有許多同名的物件,但由於不同版本所支援的成員(屬性、事件、方法)則有所不同,開發工具適時的提供了這些支援,讓Multi-Targeting這個功能在真實世界的專案開發應用上更有價值。

        上面介紹的是空專案,如果您建立的是傳統的『Web應用程式專案(ASP.NET網站)』呢? 更有趣的事情發生了:
        您會看到專案比過去的預設樣本要豐富很多,是的,被社群所強烈支持的jQuery也納入了ASP.NET的預設範本當中。同時間,你會看到支援Forms驗證的帳戶管理機制(Account資料夾下)也自動地被加入(這一招是學ASP.NET MVC專案範本的,因為廣受開發社群歡迎,所以SilverlightASP.NET Web Forms現在也比照辦理),所以當您直接編譯建置並執行這個網站,不需要寫任何一行程式碼,會看到它已經是一個可以註冊新帳戶、並且有預設的登入權限管理機制的網站了:
這對於入門的開發人員來說,可謂是一個福音。

Intellisense的增強

 

        VS2010當中,也針對intellisense有所增強,你會發現,在HTML模式下,你只要輸入幾個關鍵字例如『<ra』,VS2010自動帶出的snippet會以『』圖示帶出,這時你只需要按下[Tab]鍵:
        就可以自動填入程式碼片段,接著你只需要繼續按下[Tab]鈕在關鍵部分切換並填入程式碼即可,相當幅度的加快了在HTML模式下的程式碼撰寫速度。如果你常撰寫JavaScript,還會發現現在的VS2010還完整的支援了jQueryJavaScriptintellisense
這對於開發人員來說真的非常方便。

支援Search Engine Optimization

 

        當然,除了這些範本與開發環境上的擴充之外,在ASP.NET Web Forms本身也有相當多的增強,首先我們看到的是SEO(Search Engine Optimization)的支援。

        對於很多企業來說,自家的網頁在搜尋引擎上能否被快速的找到並且呈現出正確的資訊,是相當重要的課題。在新版的ASP.NET 4當中,增加了Page.MetaKeywords以及Page.MetaDescription這兩個屬性,這讓開發人員可以輕易的在網頁中加入可供搜尋引擎檢索的訊息:
EX
protected void Page_Load(object sender, EventArgs e)
{
    Page.MetaKeywords = "ASP.NET 4";
    Page.MetaDescription = "這是一個呈現ASP.NET 4最新技術的專業網站...";
}


當然,開發人員也可以透過.aspx的頁面修飾字來處理:
EX
<%@ Page Language="C#"  MetaKeywords="ASP.NET 4"
|MetaDescription="
這是一個呈現ASP.NET 4最新技術的專業網站..."
AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="ASP.NET_Blank.WebForm1" %>


這些訊息對於搜尋引擎來說有相當大的幫助。

ViewState的範圍限制

 

        在效能提升的部分,過去ASP.NET的開發人員大概都知道,對於使用了大量控制項的ASP.NET頁面來說,ViewState是一個令人困擾的問題,它讓網頁大小快速的膨脹造成postback時的負擔,在早期的ASP.NET版本中,ViewState的控制得要針對一個個控制項分別進行,當頁面上的控制項一多時,對開發人員來說又是個額外的負擔。

        ASP.NET 4當中,則增加了『ViewStateMode』屬性,讓我們得以透過下面這樣的指令碼,針對特定的範圍來控制ViewState
EX
<asp:PlaceHolder ID="PlaceHolder1" runat="server" ViewStateMode="Disabled">
    Disabled: <asp:Label ID="label1" runat="server" Text="[DeclaredValue]" /><br />
        <asp:PlaceHolder ID="PlaceHolder2" runat="server" ViewStateMode="Enabled">
                Enabled: <asp:Label ID="label2" runat="server" Text="[DeclaredValue]" />
            </asp:PlaceHolder>
    </asp:PlaceHolder>


        如此一來,開發人員就不需要再針對每一個控制項來逐一設定,而可以針對一群控制項進行ViewState的設置,也算是貼心的設計了。

Cache存放方式的客製支援

 

        關於效能的部分,還有一個重要的機制,過去ASP.NET 3.x時代,Web Forms已經提供了相當優秀的Cache技術,讓開發人員可以透過Cache盡可能的降低伺服器端的負擔,以加快網頁的下載速度,但在預設狀況下Cache資料永遠是儲存在記憶體中,而ASP.NET 4.0則讓我們更有彈性,可以針對不同情境下的需求,將Cache資料存放在不同的位置(例如硬碟、或資料庫)

您可以透過實作OutputCacheProvider來完成這樣的工作,您只需要實作底下這四個Method
EX
public class MyOutputCacheProvider : System.Web.Caching.OutputCacheProvider
{
    public override object Add(string key, object entry, DateTime utcExpiry)    {
        throw new NotImplementedException();
    }
    public override object Get(string key)    {
        throw new NotImplementedException();
    }
    public override void Remove(string key)    {
        throw new NotImplementedException();
    }
    public override void Set(string key, object entry, DateTime utcExpiry)    {
        throw new NotImplementedException();
    }
}


並且在Web.Config中將預設的Cache Provider指向我們所設計的『MyOutputCacheProvider』即可:
EX
<caching>
  <outputCache defaultProvider="MyCache">
    <providers>
      <add name="MyCache" type="MyOutputCacheProvider, DllName"/>
    </providers>
  </outputCache>
</caching>


        如此一來,只要您的ASP.NET頁面使用到『OutputCache』時,相關的Cache資料的儲存就會導入到您所客製的儲存機制中。

Client ID的明確化

 

        有一個長久以來一直存在的問題,隨著這幾年瀏覽器用戶端程式碼(例如JavaScript/jQuery…)的盛行,被更強烈的突顯了出來,那就是ASP.NET控制項的ClientID

        過去ASP.NETClientID一直是一個常常困擾開發人員的問題,主要的原因是APS.NETRenderHTML網頁到用戶端時,ClientID常常是動態且無法確定的,特別是ASP.NET頁面加上了master-pageUpdatePanel、或是那些會隨著資料錄數量而可能動態產生出不同資料列的GridViewListViewRepeater控制項之後, ClientID則更加的不可測了。

        面對這個問題,ASP.NET 4提出了新的ClientIDMode屬性,可透過底下四種不同的設置值來決定ClientIDRender方式,分別是:AutoIDStaticPredictable、與Inhert。開發人員可以在程式碼中透過屬性來設定ClientID產生的方式。

        例如,當您在使用ListView控制項來顯示多筆資料時,可同時設置ClientIDMode屬性為"Predictable",並且把ClientIDRowSuffix設置為『CustomerID ( CustomerID為欄位名稱)
EX
this.ListView1.ClientIDMode = System.Web.UI.ClientIDMode.Predictable;
this.ListView1.ClientIDRowSuffix = "CustomerID".Split(',');

        如此一來,您會發現Render出的HTML碼當中,ClientID是跟著我們提供的CustomerID(資料庫CustomerID欄位的值)
 
EX
 (......)
<input name="ListView1$ctrl0$Textbox1" type="text" value="ALFKI"  id="ListView1_Textbox1_ALFKI" />
<input name="ListView1$ctrl1$Textbox1" type="text" value="ANATR" id="ListView1_Textbox1_ANATR" />
<input name="ListView1$ctrl2$Textbox1" type="text" value="ANTON" id="ListView1_Textbox1_ANTON" />
<input name="ListView1$ctrl3$Textbox1" type="text" value="AROUT" id="ListView1_Textbox1_AROUT" />
<input name="ListView1$ctrl4$Textbox1" type="text" value="BERGS" id="ListView1_Textbox1_BERGS" />                                                                                  (......)

        這對於需要撰寫用戶端程式碼(例如JavaScript)的開發人員來說,將可輕鬆的明確得知透過ASP.NET從後端動態產生的HTML碼中,實際上對應到的DOM元素名稱為何,不再需要如同瞎子摸象般的胡亂猜測了。

反過來說,如果您將ClientIDMode屬性改為AutoID,則呈現出的HTML將會變成連續編號:
EX
<input name="ListView2$ctrl0$Textbox2" type="text" value="ALFKI" id="ListView2_ctrl0_Textbox2" />           
<input name="ListView2$ctrl1$Textbox2" type="text" value="ANATR" id="ListView2_ctrl1_Textbox2" />
<input name="ListView2$ctrl2$Textbox2" type="text" value="ANTON" id="ListView2_ctrl2_Textbox2" />

如同過去的ASP.NET預設狀況,若您設定為static則每一個動態產生的HTML控制項的id都會變成一樣的了。

結語

 

        從上面的介紹當中您一定已經發現,由於ASP.NET Web Forms已經是一個很成熟的開發技術,儘管ASP.NET Web Forms 4.0當中看似都不是相當大幅度的調整(我想現在開發人員似乎也不太歡迎太大幅度的改變J),但卻都是針對過去ASP.NET開發人員每天都會遭遇到的問題著手,預期這些改變將可以相當有效的提升開發速度以及改善。

        除了上面這些的介紹之後,在ASP.NET WebForms中,還包含了對URL Routing的支援、針對LINQ查詢機制的元件、以及其它控制項的功能升級和擴充,這些部分我們將在後面繼續為讀者介紹。

沒有留言:

張貼留言