共用方式為


逐步解說:使用 IPersonalizable 實作 Web 組件個人化

更新:2007 年 11 月

本逐步解說將示範如何將使用者控制項實作為可個人化的 Web 組件控制項,藉以提供使用者專屬的預設值。

這種控制項最顯著的特性是其可個人化的屬性都存放在非實值型別變數中。在上述情形下,值都是存放在 BulletedList 控制項中。這意味著系統無法得知使用者是在何時變更清單中的值。本逐步解說將示範如何通知系統這些值已變更,所以它們可以保留供日後使用。如果您是以個別使用者為基礎建立可自訂的線上表單,則這可能有所幫助。Web 組件個人化可以讓系統辨認使用者,方便下次瀏覽網站時可以自動還原使用者的預設表單值。

注意事項:

在本逐步解說中您將建立的使用者控制項不繼承自 WebPart 類別 (Class),但使用者控制項可以做為 WebPart 控制項。在本逐步解說期間,您會將使用者控制項加入至 WebPartZoneBase 區域。這樣可以讓 ASP.NET 將使用者控制項包裝在 GenericWebPart 控制項中,然後使用者控制項將和任何其他 WebPart 控制項一樣運作,並將允許您瀏覽個人化。

在瀏覽這份逐步解說期間,您將瞭解如何:

  • 使用可個人化的屬性建立使用者控制項,該屬性值可以儲存在長期儲存裝置中。

  • 顯示使用者專屬的預設值。

  • 使用區域中的使用者控制項,做為真正的 WebPart 控制項。

注意事項:

這種型別的應用程式可以使用 ASP.NET 設定檔開發。然而,在這種情況下,不像是在購物車應用程式中,要儲存在整個應用程式內重複使用之使用者的相關資訊。而是為每個控制項儲存使用者專屬的偏好設定或設定,以每頁為基礎。如需設定檔的詳細資訊,請參閱 ASP.NET 設定檔屬性概觀

必要條件

若要完成這個逐步解說,您將需要:

  • 在要裝載 (Host) 站台之電腦上安裝並設定的網際網路資訊服務 (IIS)。如需安裝和設定 IIS 的詳細資訊,請參閱安裝程式所附的 IIS 說明文件,或者參閱 Microsoft TechNet 網站上的 IIS 線上文件:Internet Information Services 6.0 技術資源 (英文)。

  • 可以識別個別使用者的 ASP.NET 網站。如果您已經設定了這類的站台,即可使用該站台做為此逐步解說的起點。除此以外,如需建立虛擬目錄或網站的詳細資訊,請參閱 HOW TO:在 IIS 5.0 和 6.0 中建立和設定虛擬目錄

  • 已設定的個人化提供者和資料庫。Web 組件個人化預設是啟用的狀態,並搭配 Microsoft SQL Server Standard Edition (SSE) 使用 SQL 個人化提供者 (SqlPersonalizationProvider) 存放個人化資料。本逐步解說會使用 SSE 和預設的 SQL 提供者。如果您已經安裝 SSE,則不需要進行任何組態設定。SSE 是 Microsoft Visual Studio 2005 的選擇性安裝部分,或者也可從 Microsoft.com 免費下載取得。若要使用其中一個 SQL Server 的完整版本,您就必須安裝和設定 ASP.NET 應用程式服務資料庫,並設定 SQL 個人化提供者以連接至該資料庫。如需詳細資訊,請參閱建立及設定 SQL Server 的應用程式服務資料庫。您也可以建立和設定自訂的提供者,以便使用其他非 SQL 資料庫或儲存方案。如需詳細資訊和程式碼範例,請參閱實作成員資格提供者

建立含有參考型別變數的可個人化之使用者控制項

在本逐步解說的這一部分中,您將建立可輸入 Web 網站之易記名稱和 URL 的使用者控制項。當按一下 [Save] 按鈕時,便會將易記名稱加入至 BulletedList 控制項。Web 組件個人化功能會以個別使用者為基礎存放這些值,所以每次使用者存取其他網頁或新工作階段 (Session) 中的控制項時,系統便會顯示已儲存的 BulletedList 值。

注意事項:

您無需啟用 Web 組件個人化,它已預設為啟用。如需個人化的詳細資訊,請參閱 Web 組件個人化概觀

若要建立可個人化的使用者控制項

  1. 在文字編輯器中,建立新檔案來包含使用者控制項,再將其命名為 UrlList.ascx,然後儲存到 Web 目錄中。實作控制項之行為的程式碼是包含在個別的檔案中,如步驟 4 所示。

  2. 在新檔案中,以所使用的程式語言加入控制項指示詞,如下列範例所示。

    <%@ Control Language="VB" AutoEventWireup="false"  
    CodeFile="UrlList.ascx.vb" Inherits="WebParts_UrlList" %>
    
    <%@ Control Language="C#" AutoEventWireup="true" 
    CodeFile="UrlList.ascx.cs" Inherits="WebParts_UrlList" %>
    
  3. 在指示詞下面,加入下列項目來代表控制項的使用者介面 (UI)。

    <table>
    
    <tr>
        <td> 
            <asp:Label ID="NameLabelID" Text="Name: "  />
        </td>
        <td>
            <asp:TextBox ID="NameTextBoxID"  />
        </td>
    </tr>
    
    <tr>
        <td>
            <asp:Label ID="UrlLabelID1" Text="Url:  "  />
        </td>
        <td>
            <asp:TextBox ID="UrlTextBoxID"  />
        </td>
    </tr>
    
    <tr>
        <td>
            <asp:Button ID="SaveID"  
                OnClick="SaveButton_Click" Text="Save" />
        </td>
        <td>
            <asp:Button ID="ResetID"  
                OnClick="ResetButton_Click" Text="Reset" />
        </td>
    </tr>
    
    </table>
    
    <div>
         // This is the complex variable whose status 
         // must be preserved.
        <asp:BulletedList 
            ID="BulletedListID" 
            DisplayMode="HyperLink"  Target="_blank" />
    
    </div>
    
  4. 建立另一個新檔案做為夥伴檔,並在其中加入下列程式碼。下列程式碼代表夥伴檔 (UrlList.ascx.vb 或 UrlList.ascx.cs,視您所使用的語言而定),它會實作前述 UrlList.ascx 控制項的行為。這個程式碼分成兩部分,第一部分包含處理使用者輸入和頁面載入事件的程式碼,第二部分則包含其他實作 IPersonalizable 介面的程式碼。這樣可以保留 BulletedList 值,也就是使用者控制項的個人化。這個範例會實作 LoadSaveIsDirty 介面成員。

    ' UrlList.ascx.vb
    Imports System
    Imports System.Collections
    Imports System.Web
    Imports System.Web.UI
    Imports System.Web.UI.WebControls
    Imports System.Web.UI.WebControls.WebParts
    
    Partial Class WebParts_VB_UrlList
        Inherits System.Web.UI.UserControl
        Implements IPersonalizable
    
        Private _userUrls As ArrayList
        Private _listDirty As Boolean
    
        ' This code implements the IPersonalizable members.
    
        Public Overridable ReadOnly Property IsDirty() As Boolean _
        Implements System.Web.UI.WebControls.WebParts.IPersonalizable.IsDirty
    
            Get
                Return _listDirty
            End Get
        End Property
    
    
        Public Overridable Shadows Sub Load(ByVal state As PersonalizationDictionary) _
        Implements System.Web.UI.WebControls.WebParts.IPersonalizable.Load
    
    
            If Not (state Is Nothing) Then
    
                Dim userUrlsEntry As PersonalizationEntry = state("userUrls")
                If Not (userUrlsEntry Is Nothing) Then
                    _userUrls = CType(userUrlsEntry.Value, ArrayList)
                End If
            End If
    
        End Sub 'Load
    
        Public Overridable Sub Save(ByVal state As PersonalizationDictionary) _
          Implements System.Web.UI.WebControls.WebParts.IPersonalizable.Save
    
            If Not (_userUrls Is Nothing) AndAlso _userUrls.Count <> 0 Then
                state("userUrls") = New PersonalizationEntry(_userUrls, _
                PersonalizationScope.User)
            End If
    
        End Sub
    
        ' This code handles the user's input.
        Protected Sub SaveButton_Click(ByVal sender As Object, _
        ByVal e As EventArgs)
    
            Dim name As String = NameTextBoxID.Text.Trim()
            Dim url As String = UrlTextBoxID.Text.Trim()
    
            Dim p As New Pair(name, url)
    
            If _userUrls Is Nothing Then
                _userUrls = New ArrayList()
            End If
            _userUrls.Add(p)
    
            BulletedListID.Items.Add(New ListItem(CStr(p.First), _
            CStr(p.Second)))
    
            _listDirty = True
    
        End Sub 'SaveButton_Click
    
    
        Protected Sub ResetButton_Click(ByVal sender As Object, _
        ByVal e As EventArgs)
    
            _userUrls = New ArrayList()
    
             BulletedListID.Items.Clear()
    
            _listDirty = True
    
        End Sub 'ResetButton_Click 
    
    
        Protected Sub Page_Load(ByVal sender As Object, _
        ByVal e As EventArgs)
            If Not (_userUrls Is Nothing) Then
                BulletedListID.Items.Clear()
                Dim p As Pair
                For Each p In _userUrls
                    BulletedListID.Items.Add(New _
                    ListItem(CStr(p.First), CStr(p.Second)))
                Next p
            End If
    
        End Sub 'Page_Load
    
    End Class
    
    // UrlList.ascx.cs
    using System;
    using System.Collections;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    
    public partial class WebParts_UrlList : System.Web.UI.UserControl, 
        IPersonalizable
    {
        private ArrayList _userUrls;
        private bool _listDirty;
    
           // This code implements the IPersonalizable members.
    
        public new void Load(PersonalizationDictionary state)
        {
            if (state != null)
            {
    
                PersonalizationEntry userUrlsEntry = state["userUrls"];
                if (userUrlsEntry != null)
                {
                    _userUrls = (ArrayList)userUrlsEntry.Value;
                }
    
            }
        }
    
        public void Save(PersonalizationDictionary state)
        {
    
            if ((_userUrls != null) && (_userUrls.Count != 0))
            {
                state["userUrls"] =
                    new PersonalizationEntry(_userUrls, PersonalizationScope.User);
            }
    
        }
    
        public virtual bool IsDirty
        {
            get
            {
                return _listDirty;
            }
        }
    
           // This code handles the user's input.
    
        protected void Page_Load(object sender, EventArgs e)
        {
            if (_userUrls != null)
            {
                BulletedListID.Items.Clear();
                foreach (Pair p in _userUrls)
                {
                    BulletedListID.Items.Add(
                        new ListItem((string)p.First, (string)p.Second));
                }
            }
    
        }
    
        protected void SaveButton_Click(object sender, EventArgs e)
        {
            string name = NameTextBoxID.Text.Trim();
            string url = UrlTextBoxID.Text.Trim();
    
            Pair p = new Pair(name, url);
    
            if (_userUrls == null)
            {
                _userUrls = new ArrayList();
            }
            _userUrls.Add(p);
    
            BulletedListID.Items.Add(
                    new ListItem((string)p.First, (string)p.Second));
    
            _listDirty = true;
        }
    
    
        protected void ResetButton_Click(object sender, EventArgs e)
        {
    
            _userUrls = new ArrayList();
    
             BulletedListID.Items.Clear();
    
            _listDirty = true;
    
        }
    
    } 
    
  5. 將檔案命名為 UrlList.ascx.vb 或 UrlList.ascx.cs (視您所使用的語言而定),並將其儲存到 Web 網站的根目錄中。

    安全性注意事項:

    這個控制項有一個可接受使用者輸入的文字方塊,這可能會造成安全性威脅。在 Web 網頁中的使用者輸入可能會含有惡意的用戶端指令碼。ASP.NET Web 網頁預設會驗證使用者輸入,以確保輸入中未包含 HTML 項目或指令碼。一旦啟用了驗證,就不需要明確檢查使用者輸入中的指令碼或 HTML 項目。如需詳細資訊,請參閱指令碼攻擊概觀

將使用者控制項引用為 Web 組件控制項

既然已經使用可個人化的屬性建立使用者控制項,就可以建立 Web Form 網頁,以將使用者控制項裝載為 Web 組件控制項。

注意事項:

您必須將控制項裝載為 Web 組件控制項,個人化才有作用。

若要將使用者控制項引用為 Web 組件控制項

  1. 在文字編輯器中,建立新檔案。將頁面宣告加入至檔案的開頭,如下列範例所示。

    <%@ page language="VB" %>
    
    <%@ page language="C#" %>
    
  2. 在網頁宣告下,加入宣告以引用先前建立的使用者控制項,如下列範例所示。

    <%@ Register tagprefix="UserControl" tagname="UrlList" 
    src="UrlList.ascx" %>
    
    <%@ Register tagprefix="UserControl" tagname="UrlList" 
    src="UrlList.ascx" %>
    
  3. 在控制項引用下,加入下列基本網頁結構,以將使用者控制項裝載為 Web 組件控制項。

    注意事項:

    對於用做 Web 組件控制項的使用者控制項,網頁必須包含 <asp:webpartmanager> 項目,且使用者控制項必須接續包含在 <asp:webpartzone> 項目和 <zonetemplate> 項目內,如下列範例所示。

    <html>
    <head >
        <title>Personalizable User Control</title>
    </head>
    <body>
        <form id="form1" >
          <asp:WebPartManager ID="mgr"  />
            <div>
              <asp:WebPartZone ID="WebPartZone1" >
                <ZoneTemplate>
                  < UserControl:UrlList ID="AccUserID" 
                    title="URL List WebPart" />  
                </ZoneTemplate>
              </asp:WebPartZone>
            </div>    
        </form>
    </body>
    </html>
    
  4. 將檔案命名為 UrlList.aspx,並將其儲存到與使用者控制項相同的目錄中。

    您現在已經建立可個人化的使用者控制項,並將其引用為 Web Form 網頁中的 Web 組件控制項。

最後步驟是測試使用者控制項。

若要測試可個人化的使用者控制項

  1. 將 UrlList.aspx 網頁載入瀏覽器。

  2. 在 [Name] 和 [URL] 欄位中輸入值,然後按一下 [Save Form Values] 按鈕。

  3. 關閉瀏覽器。

  4. 再次在瀏覽器中載入網頁。

    您先前輸入的值應該出現在表單中。這些值是已儲存在 BulletedList 控制項中的值,而且是當您在瀏覽器中重新載入了網頁時已從資料庫中還原的值。

  5. 在表單中輸入新值,但是請不要按一下按鈕儲存它們。關閉瀏覽器。

  6. 再次在瀏覽器中載入網頁。表單中應該會出現您當初輸入並儲存於個人化屬性的值。

後續步驟

這個逐步解說示範了關於使用可個人化之屬性建立使用者控制項的基本工作。您建立的控制項允許您儲存特定控制項和網頁之使用者專屬的設定,並當使用者在新的瀏覽器工作階段中重新造訪網頁時顯示那些儲存的設定。另外,建議您再深入研究的重點包括:

請參閱

概念

ASP.NET Web 組件概觀

Web 組件個人化概觀