.Net Framework 4.5與Visual Studio 11- ASP.NET 4.5新功能(1)

by vivid 30. 十一月 2011 01:10

.NET Magazine國際中文電子雜誌
作 者:許薰尹
審 稿:張智凱
文章編號:N111111803
出刊日期:2011/11/30

ASP.NET 4.5版中包含許多新特性來開發網站應用程式,Visual Studio 11 Developer Preview版開發工具也有許多改善,讓撰寫網頁的動作更為簡化,本篇文章將介紹一些開發工具提供的新特性。

開發工具新增功能

在Visual Studio 2010設計ASP.NET網頁時,有很多工作我們會透過「Smart Task」來完成,例如底下有一個Entity Data Source控制項,透過「Smart Task」可以設定它的資料來源,參考圖1所示。

clip_image002

圖 1:透過Smart Task設定控制項屬性。

現在Visual Studio 11工具「Source View」編輯畫面也可以使用「Smart Task」,只要將滑鼠游標停留在控制項的開始標籤上方,就會自動顯示一條藍色的底線,只要點選它或按下「CTRL+ .」叫出「Smart Task」視窗,參考圖2所示。

clip_image004

圖 2:在「Source View」編輯畫面使用「Smart Task」。

在「Source View」編輯畫面也可以註冊事件,類似WPF應用程式的事件註冊動作。例如以下範例利用EntityDataSource透過ADO.NET Entity Data Model讀取AdventureWorks資料庫中Contacts資料表的ContactID、Title 與FirstName三個欄位的資料,透過資料繫結技術將資料呈現在GridView控制項中顯示。預設GridView控制項會使用BoundField來顯示資料:

<form id = "form1" runat = "server" >
    <div>
        <asp:Label ID = "Label1" runat = "server" Text = "Label" > </asp:Label>
    </div>   
    <asp:GridView ID = "GridView1" runat = "server" AutoGenerateColumns = "False"
        DataSourceID = "EntityDataSource1" >
        <Columns>
            <asp:BoundField DataField = "ContactID" HeaderText = "ContactID" ReadOnly = "True"
                SortExpression = "ContactID" />
            <asp:BoundField DataField = "Title" HeaderText = "Title" ReadOnly = "True"
                SortExpression = "Title" />
            <asp:BoundField DataField = "FirstName" HeaderText = "FirstName" ReadOnly = "True"
                SortExpression = "FirstName" />
        </Columns>
    </asp:GridView>
    <asp:EntityDataSource ID="EntityDataSource1" runat = "server"
        ConnectionString = "name=AdventureWorksEntities"
        DefaultContainerName = "AdventureWorksEntities" EnableFlattening = "False"
        EntitySetName = "Contacts" Select = "it.[ContactID], it.[Title], it.[FirstName]">
    </asp:EntityDataSource>   
    </form>

EntityDataSource控制項有一個Selecting事件,這個事件在讀取資料庫資料的動作發生時自動觸發。我們希望每回從資料庫擷取資料時,能夠將存取時間顯示在畫面的Label控制項上。當你利用Visual Studio 11的HTML編輯工具在EntityDataSource控制項開頭標籤輸入「OnSelecting=」字串時,Visual Studio 11便自動跳出一個「Create New Event」選項以註冊事件與建立事件處理常式,參考圖3所示:clip_image006

圖 3:註冊事件與建立事件處理常式。

這時只要按一次鍵盤的「Tab」鍵,就會自動產生事件處理常式,我在事件處理常式中,讀取目前伺服器的時間顯示在Label控制項上:

protected void EntityDataSource1_Selecting( object sender, EntityDataSourceSelectingEventArgs e )
    {
      Label1.Text = "Fetching Data : " + System.DateTime.Now.ToString();
    }

執行結果參考圖4所示:

clip_image008

圖 4:執行結果。

封裝使用者控制項

在設計網頁時,有時我們會將經常出現的HTML標籤封裝成利於重複使用的單位- 使用者控制項(User Control,附檔名為ASCX檔案),以便在網頁中重複地使用。Visual Studio 11 Developer Preview提供一個小技巧,可以將網頁中的標籤封裝成ASCX檔案。例如,ASPX網頁中包含以下三個控制項:Label、TextBox與RequiredFieldValidator:

<asp:Label ID = "Label1" runat = "server" Text = "Input Text" > </asp:Label>
    <asp:TextBox ID = "TextBox1" runat = "server"></asp:TextBox>
    <asp:RequiredFieldValidator
        ID = "RequiredFieldValidator1" runat = "server"
        ErrorMessage = "RequiredFieldValidator" ControlToValidate = "TextBox1"
        ForeColor = "Red"> * </asp:RequiredFieldValidator>

在Visual Studio 11 Developer Preview 的HTML編輯工具中,可以將這些HTML標籤選取,然後按滑鼠右鍵,從突顯式選單中選取「Extract to User Control」選項,參考圖5所示:

clip_image010

圖 5:Extract to User Control。

接著你就會看到「Save as」對話盒,你可以輸入想要使用的使用者控制項的檔案名稱,參考圖6所示:

clip_image012

圖 6:設定使用者控制項名稱。

當你按下「OK」按鈕後, ASPX網頁內容上方利用Register註冊使用者控制項,原來HTML標籤所在的地方,便改用使用者控制項的標籤來顯示:

<%@ Page Language = "C#" AutoEventWireup = "true" CodeFile = "2_UserCtrl.aspx.cs" Inherits = "_2_UserCtrl" %>

<%@ Register Src = "~/MyTextBox.ascx" TagPrefix = "uc1" TagName = "MyTextBox" %>

<!DOCTYPE html>

<html xmlns = http://www.w3.org/1999/xhtml >
<head runat = "server" >
    <title></title>
</head>
<body>
    <form id = "form1" runat = "server">

    <uc1:MyTextBox runat = "server" ID = "MyTextBox" />
    <br />
    <asp:Button ID = "Button1" runat = "server" Text = "Button" />
    </form>
</body>
</html>

另外專案中就會多出一個MyTextBox.Ascx檔案,檔案內容如下:

<%@ Control Language = "C#" AutoEventWireup = "true" CodeFile = "MyTextBox.ascx.cs" Inherits = "MyTextBox" %>

<asp:Label ID = "Label1" runat = "server" Text = "Input Text"> </asp:Label>
<asp:TextBox ID = "TextBox1" runat = "server"> </asp:TextBox>
<asp:RequiredFieldValidator ID = "RequiredFieldValidator1" runat = "server" ErrorMessage = "RequiredFieldValidator"
    ControlToValidate = "TextBox1" ForeColor = "Red" > * </asp:RequiredFieldValidator>

不過目前據筆者的測試,若使用者控制項包含程式碼,像是事件處理常式等,目前的Visual Studio 11 Developer Preview版本便無法將其封裝,你可能得手動處理,舉例來說,若ASPX網頁內容如下,包含一個TextBox、Button與Label控制項:

<%@ Page Language = "C#" AutoEventWireup = "true" CodeFile = "3_UCDemo.aspx.cs" Inherits = "_3_UCDemo" %>
<!DOCTYPE html>
<html xmlns = http://www.w3.org/1999/xhtml >
<head runat = "server" >
    <title></title>
</head>
<body>
    <form id = "form1" runat = "server" >
    <div>
        <asp:TextBox ID = "TextBox1" runat = "server"> </asp:TextBox>
        <asp:Button ID = "Button1" runat = "server" OnClick = "Button1_Click" Text = "Click" />
        <br />
        <asp:Label ID = "Label1" runat = "server"> </asp:Label>
    </div>
    </form>
</body>
</html>

而網頁相關聯的程式碼後置cs檔案內容如下,Button若被按下觸發Click事件時,會將文字方塊輸入的字串顯示在Label控制項上:

public partial class _3_UCDemo : System.Web.UI.Page
{
  
    protected void Button1_Click(object sender, EventArgs e)
    {
        Label1.Text = TextBox1.Text ;
    }
}

但當你將TextBox、Button與Label控制項同時選取,封裝成使用者控制項後,Button1_Click事件處理常式並不會被複製到ASCX檔案中。

WAI-ARIA支援

WAI-ARIA ( Accessible Rich Internet Applications Suite) 是W3C制定中的一個標準,定義了一個準則,讓身障人士能夠更容易存取使用Ajax、HTML、JavaScript設計的網站應用程式,或網際網路的內容。Visual Studio 11 Developer Preview現在已經支援這個標準。

HTML編輯工具 - 智慧型感知功能

在Visual Studio 11 Developer Preview中撰寫支援HTML5網頁時,HTML編輯工具提供了智慧型感知(IntelliSense)功能,方便撰寫程式碼,例如當你使用到HTML 5的Canvas項目時,便會自動顯示提示,參考圖7所示。

clip_image014

圖 7:HTML智慧型感知功能。

HTML編輯工具 - HTML 5程式碼片段功能

在Visual Studio 11 Developer Preview中撰寫支援HTML5網頁的動作變的更簡單了,只要善用HTML 5程式碼片段功能,就可以很快達成任務。例如想要在HTML網頁中加入一個清單方塊,可以輸入部份的HTML標籤,Visual Studio 11 Developer Preview會自動提醒可以使用程式碼片段功能,參考圖8所示:

clip_image016

圖 8:HTML 5程式碼片段功能。

這時只要按下Tab鍵兩次,程式碼片段功能就會自動填入<li>項目,參考圖9所示:

clip_image018

圖 9:HTML 5程式碼片段功能。

HTML編輯工具 - HTML標籤自動重新命名

在編輯HTML標籤方面,Visual Studio 11 Developer Preview開發工具提供一個貼心的功能,只要你修改了開頭或結尾標籤,它就會自動將相符的結尾、開頭標籤的自動重新命名。例如以下範例,當修改開頭的<title>標籤為<titl>時,結尾標籤就自動改為<titl>,參考圖10所示。

clip_image020

圖 10:HTML標籤自動重新命名。

HTML編輯工具 – 自動縮排

在Visual Studio 2010編輯HTML標籤時,當你輸入開頭標籤然後按下鍵盤Enter鍵時,除了幫你產生結尾的</div>之外,會將游標停留在結尾的</div>標籤之前,如下圖紅色標記所示:

clip_image022

圖 11:Visual Studio 2010 HTML縮排功能。

而Visual Studio 11 Developer Preview則會在開頭<div>和結尾的</div>標籤之間插入一個空白行,並讓開頭標籤和結尾自動縮排對齊,然後將游標停留在空白行開頭,參考圖12所示:

clip_image024

圖 12:Visual Studio 11 Developer Preview HTML縮排功能。

HTML編輯工具 – IntelliSense清單過濾功能

在Visual Studio 2010編輯HTML標籤時工具會透過IntelliSense功能表列出可使用的清單供開發者選擇,底下範例輸入「<di」字串,但是清單中還包含了其它非「<di」字串開頭的選項,參考圖13所示:

clip_image026

圖 13:Visual Studio 2010 IntelliSense清單。

而Visual Studio 11 Developer Preview會自動進行篩選,將符合查詢條件的項目列出,參考圖14所示:

clip_image028

圖 14:Visual Studio 11 Developer Preview IntelliSense清單過濾功能。

強型別的資料控制項樣版

ASP.NET 4.5網頁控制項現在具備強型別的資料樣版功能,在設計資料存取網頁時,非常有幫助。我們先來看一個ASPX網頁,網頁中包含一個GridView控制項顯示以EntityDataSource控制項,透過ADO.NET Entity Data Model技術取回的AdventureWorks資料庫Contact資料表內容,GridView控制項利用BoundField來顯示ContactID、Title、FirstName與LastName欄位值,我們可以改用樣版資料行來自顯示的內容:

<asp:GridView ID = "GridView1" runat = "server" AutoGenerateColumns = "False"
        DataKeyNames = "ContactID" DataSourceID="EntityDataSource1" >
        <Columns>
            <asp:BoundField DataField = "ContactID" HeaderText = "ContactID" ReadOnly = "True"
                SortExpression = "ContactID" />
            <asp:BoundField DataField = "Title" HeaderText = "Title" SortExpression = "Title" />
            <asp:BoundField DataField = "FirstName" HeaderText = "FirstName"
                SortExpression = "FirstName" />
            <asp:BoundField DataField = "LastName" HeaderText = "LastName"
                SortExpression = "LastName" />
        </Columns>
    </asp:GridView>
    <asp:EntityDataSource ID = "EntityDataSource1" runat = "server"
        ConnectionString = "name=AdventureWorksEntities"
        DefaultContainerName = "AdventureWorksEntities" EnableDelete = "True"
        EnableFlattening = "False" EnableInsert = "True" EnableUpdate = "True"
        EntitySetName = "Contacts" >
    </asp:EntityDataSource>

筆者利用GridView控制項的「Smart Task」選項,編輯這些欄位,將BoundField轉換成Template Field,參考圖15所示:

clip_image030

圖 15:編輯GridView欄位。

參考圖16所示,只要選取欄位,然後點選「Field」對話盒右下方的「Convert this Field into a Template Field」超連結,就可以轉換成樣板資料行:

clip_image032

圖 16:將Bound Field轉換成樣板資料行。

透過上述步驟,將Title、FirstName、LastName欄位都轉換為TemplateField,此時工具自動產生出的HTML如下:

<asp:GridView ID = "GridView1" runat = "server" AutoGenerateColumns = "False"
        DataKeyNames = "ContactID" DataSourceID = "EntityDataSource1">
        <Columns>
            <asp:BoundField DataField = "ContactID" HeaderText = "ContactID" ReadOnly = "True"
                SortExpression = "ContactID" />
            <asp:TemplateField HeaderText = "Title" SortExpression = "Title">
                <EditItemTemplate>
                    <asp:TextBox ID = "TextBox1" runat = "server" Text = '<%# Bind("Title") %>'> </asp:TextBox>
                </EditItemTemplate>
                <ItemTemplate>
                    <asp:Label ID = "Label1" runat = "server" Text = '<%# Bind("Title") %>'> </asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText = "FirstName" SortExpression = "FirstName">
                <EditItemTemplate>
                    <asp:TextBox ID = "TextBox2" runat = "server" Text = '<%# Bind("FirstName") %>'> </asp:TextBox>
                </EditItemTemplate>
                <ItemTemplate>
                    <asp:Label ID = "Label2" runat = "server" Text='<%# Bind("FirstName") %>'> </asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText = "LastName" SortExpression = "LastName">
                <EditItemTemplate>
                    <asp:TextBox ID = "TextBox3" runat = "server" Text = '<%# Bind("LastName") %>'></asp:TextBox>
                </EditItemTemplate>
                <ItemTemplate>
                    <asp:Label ID = "Label3" runat = "server" Text = '<%# Bind("LastName") %>'></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>

從中可以看出,我們利用ASP.NT 雙向的Bind語法進行資料繫結。不過若在HTML編輯工具中修改Bind語法中的內容,工具並不會提供任何提示,這致使程式出錯的機率變高。此外利用Bind語法進行繫結實際上是以晚期繫結(Late Binding)的方式處理,將字串傳入Bind方法後再行剖析,這樣就無法在設計階段善用工具提供輔助來撰寫程式碼(如IntelliSense功能)。

ASP.NET 4.5現在支援強型別的資料樣版(strongly-typed data template)來改善這個問題,大部分的資料繫結控制項可以利用ModelType屬性來指明欲繫結的資料模型之型別,然後在樣版中使用Item (單向繫結)或BindItem(雙向繫結)兩個運算式來取代先前的Bind語法:

<asp:GridView ID = "GridView1" runat = "server" AutoGenerateColumns = "False"
        DataKeyNames = "ContactID" DataSourceID = "EntityDataSource1"
        ModelType = "AdventureWorksModel.Contact">
        <Columns>
            <asp:CommandField ShowEditButton = "True" />
            <asp:BoundField DataField = "ContactID" HeaderText = "ContactID" ReadOnly = "True"
                SortExpression = "ContactID" />
            <asp:TemplateField HeaderText = "Title" SortExpression = "Title">
                <EditItemTemplate>
                    <asp:TextBox ID = "TextBox1" runat = "server" Text = '<%# BindItem.Title%>'> </asp:TextBox>
                </EditItemTemplate>
                <ItemTemplate>
                    <asp:Label ID = "Label1" runat = "server" Text = '<%# Item.Title %>'> </asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText = "FirstName" SortExpression = "FirstName">
                <EditItemTemplate>
                    <asp:TextBox ID = "TextBox2" runat = "server" Text = '<%# Binditem.FirstName %>'> </asp:TextBox>
                </EditItemTemplate>
                <ItemTemplate>
                    <asp:Label ID = "Label2" runat = "server" Text = '<%# Item.FirstName %>'> </asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText = "LastName" SortExpression = "LastName">
                <EditItemTemplate>
                    <asp:TextBox ID = "TextBox3" runat = "server" Text = '<%#Binditem.LastName %>'> </asp:TextBox>
                </EditItemTemplate>
                <ItemTemplate>
                    <asp:Label ID = "Label3" runat = "server" Text = '<%# Item.LastName %>'> </asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>

這樣的好處是,在編譯階段便會進行檢查,例如底下圖17顯示,ModelType屬性設定的AdventureWorksModel.Contact型別並沒有NameLast屬性,因此編譯時就會顯示錯誤訊息。

clip_image034

圖 17:在編譯階段便可以進行型別檢查。

不過很不幸地,使用目前測試的Visual Studio 11 Developer Preview版本,在GridView控制項中設計資料樣版時,並沒有IntelliSense的支援。但若改用Repeater控制項設計樣版時,才會有IntelliSense的效果,參考圖18所示。由此得之目前這個功能不是每個控制項的樣版都可以支援,希望在正式版本推出時能有改善。

clip_image036

圖 18:設計階段的IntelliSense支援。

Tags:

NET 開發 | 許薰尹Vivid Hsu | ASP.NET | .NET Magazine國際中文電子雜誌

新增評論




  Country flag
biuquote
  • 評論
  • 線上預覽
Loading






NET Magazine國際中文電子雜誌

NET Magazine國際中文電子版雜誌,由恆逸資訊創立於2000,自發刊日起迄今已發行超過500篇.NET相關技術文章,擁有超過40000名註冊讀者群。NET Magazine國際中文電子版雜誌希望藉於電子雜誌與NET Developer達到共同學習與技術新知分享,歡迎每一位對.NET 技術有興趣的朋友們多多支持本雜誌,讓作者群們可以有持續性的動力繼續爬文。<請加入免費訂閱>

月分類Month List