随心所欲自己定制个性化提供者(Provider)- 未整理

很多人都知道webpart框架是*提供者(Provider)模式保存个性化数据。框架缺省的和仅有的提供者(Provider)是SqlPersonalizationProvider,然而我们还有其他方法,轻松创建自己的提供者(Provider)。
我们在这里简单阐述两种定制个性化提供者办法,即Query String 个性化提供者和匿名个性化提供者。

。建造字符串序列(Query String)个性化提供者

缺省的个性化提供者只能用于指定的页面路径。一个用户可以在两个不同的页面使用不同的方法,但是不能在相同的页面采用两种不同的方法,这是在实践中常常碰见的问题。例如我们开发一个用于在线商店的Product.aspx页,需要根据页面通过Query String来显示不同的产品。

备注:我们也可以使用VirtualPathProvider解决此类问题。

SqlPersonalization 提供者是按product ID进入页面,当然不能定制不同的页面,因此必须采用Query String个性化提供者才能达到我们的目的。

下面实例包括两个页面

MovieList.aspx -- 显示电影列表,点击列表进入movieDetails.aspx
MovieDetails.aspx - 显示电影详细信息。

它们含有两个webpart:MoviePart.ascx和TextPart.ascx,并有需要下面两个支持文件:

QueryStringPersonalizationProvider - 实行定制个性化提供者。

Web.Config - 配置定制个性化提供者

我们首先了解QueryStringPersonalizationProvider 类

namespace myControls {
    using System.Web.UI.WebControls.WebParts;
    using System.Web;
    using System;
   
   
    // '' <summary>
    // '' Custom personalization provider which takes into account the
    // '' id query string parameter.
    // '' </summary>
    public class QueryStringPersonalizationProvider : SqlPersonalizationProvider {
       
        // '' <summary>
        // '' Called when data is saved to the database
        // '' </summary>
        protected override void SavePersonalizationBlob(WebPartManager webPartManager, string path, string userName, byte[] dataBlob) {
            string queryStringId = HttpContext.Current.Request("id");
            if (!(queryStringId == null)) {
                path = (path + ("?id=" + queryStringId));
            }
            base.SavePersonalizationBlob(webPartManager, path, userName, dataBlob);
        }
       
        // '' <summary>
        // '' Called when data is loaded from the database
        // '' </summary>
        protected override void LoadPersonalizationBlobs(WebPartManager webPartManager, string path, string userName, ref byte[] sharedDataBlob, ref byte[] userDataBlob) {
            string queryStringId = HttpContext.Current.Request("id");
            if (!(queryStringId == null)) {
                path = (path + ("?id=" + queryStringId));
            }
            base.LoadPersonalizationBlobs(webPartManager, path, userName, sharedDataBlob, userDataBlob);
        }
       
        // '' <summary>
        // '' Called when a user's personalization data is reset
        // '' </summary>
        protected override void ResetPersonalizationBlob(WebPartManager webPartManager, string path, string userName) {
            string queryStringId = HttpContext.Current.Request("id");
            if (!(queryStringId == null)) {
                path = (path + ("?id=" + queryStringId));
            }
            base.ResetPersonalizationBlob(webPartManager, path, userName);
        }
    }
}

在每种方法里,把querystring的参数值ID加到与正在保存的状态数据有关路径里,换句话说,状态数据与路径和querystring的参数值ID联系在一起。
然后我们要做的事是把上述类发在App_Code,在Web配置文件中将QueryStringPersonalizationProvider作为缺省的个性化提供者。
Listing 2. Web.Config

<?xml version="1.0"?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
  <connectionStrings>
    <add
      name="Northwind"
      connectionString="Server=localhost;Trusted_Connection=true;
Database=Northwind"/>
  </connectionStrings>
    <system.web>
      <webParts>
        <personalization
          defaultProvider="QueryStringPersonalizationProvider">
          <providers>
            <add
              name="QueryStringPersonalizationProvider"
              type="myControls.QueryStringPersonalizationProvider"
              connectionStringName="localSQLServer" />
          </providers>
        </personalization>
      </webParts>
    </system.web>
</configuration>


 你可以打开MovieList.aspx页面,测试 QueryStringPersonalizatonProvider。点击movie标题,进入MovieDetails.aspx页面,此时,你能在相同页面上呈现个性化MovieDetails.aspx不同版本的页面.

。创建匿名个性化提供者

缺省的SqlPersonalizationProvider只有当授权用户以后,才能存储个性化数据。对于随机访问你的用户,并不储存个性化数据。如果要求让匿名用户也能个性化webpart,例如,创建像My MSN,My Yahoo那样的定制入口页面,就不要求用户注册页面才能定制。幸好修改现有的 SqlPersonalizationProvider以适应匿名用户不是一件难事,因为 ASP.NET Framework的其他部件在其基础部分已经能识别匿名用户,这就是支持匿名用户的ASP.NET Profiles。
我们现在开始学习如何创建匿名用户个性化提供者。首先需要用 Web Part Framework修改三个标准类。第一个是创建匿名个性化提供者,
 
Listing 3. AnonSqlPersonalizationProvider.vb

namespace myControls {
    using System.Web.UI.WebControls.WebParts;
    using System.Web;
    using System;   
   
    // '' <summary>
    // '' Custom Personalizaton Provider which enables
    // '' anonymous personalization
    // '' </summary>
    public class AnonSqlPersonalizationProvider : SqlPersonalizationProvider {
       
        // '' <summary>
        // '' Saves personalization data to the database
        // '' </summary>
        protected override void SavePersonalizationBlob(WebPartManager webPartManager, string path, string userName, byte[] dataBlob) {
            if (!HttpContext.Current.Request.IsAuthenticated) {
                userName = HttpContext.Current.Request.AnonymousID;
            }
            base.SavePersonalizationBlob(webPartManager, path, userName, dataBlob);
        }
       
        // '' <summary>
        // '' Loads personalization data from the database
        // '' </summary>
        protected override void LoadPersonalizationBlobs(WebPartManager webPartManager, string path, string userName, ref byte[] sharedDataBlob, ref byte[] userDataBlob) {
            if (!HttpContext.Current.Request.IsAuthenticated) {
                userName = HttpContext.Current.Request.AnonymousID;
            }
            base.LoadPersonalizationBlobs(webPartManager, path, userName, sharedDataBlob, userDataBlob);
        }
       
        // '' <summary>
        // '' Deletes personalization data from the database
        // '' </summary>
        protected override void ResetPersonalizationBlob(WebPartManager webPartManager, string path, string userName) {
            if (!HttpContext.Current.Request.IsAuthenticated) {
                userName = HttpContext.Current.Request.AnonymousID;
            }
            base.ResetPersonalizationBlob(webPartManager, path, userName);
        }
       
        // '' <summary>
        // '' Determines whether the page opens in User or Shared
        // '' personalization scope
        // '' </summary>
        public override PersonalizationScope DetermineInitialScope(WebPartManager webPartManager, PersonalizationState loadedState) {
            return webPartManager.Personalization.InitialScope;
        }
    }
}

AnonPersonalizationProvider 将覆盖SqlPersonalizationProvider类型第四种方法。如果用户匿名,LoadPersonalizationBlob(), SavePersonalizationBlob(), 和 ResetPersonalizationBlob() 方法都是使用用户匿名的ID而不是用户正常的用户名,DetermineInitialScope()也一样被覆盖,因为实行该方法将自动将匿名用户放进共享个性化范围。

下步我们将标准的WebPartPersonalization类型。该类标准版本将防止匿名用户进入修改状态信息。下面是AnonWebPartPersonalization类。
Listing 4. AnonWebPartPersonalization.vb

namespace myControls {
    using System.Web.UI.WebControls.WebParts;
    using System.Web;
    using System.Collections;
    using System;
   
   
    // '' <summary>
    // '' Overrides the standard WebPartPersonalization class
    // '' to enable anonymous users to modify state.
    // '' </summary>
    public class AnonWebPartPersonalization : WebPartPersonalization {
       
        public AnonWebPartPersonalization(WebPartManager webPartManager) :
                base(webPartManager) {
        }
       
        protected override IDictionary UserCapabilities {
            get {
                if ((HttpContext.Current.Request.IsAuthenticated == true)) {
                    return base.UserCapabilities;
                }
                else {
                    Hashtable capabilities = new Hashtable();
                    capabilities.Add(WebPartPersonalization.ModifyStateUserCapability, WebPartPersonalization.ModifyStateUserCapability);
                    return capabilities;
                }
            }
        }
    }
}

 在Listing 5例子中,UserCapabilities属性已经覆盖,新的属性将保证所有用户,甚至匿名用户都有能力修改状态信息。
下一步由于创建了定制WebPartPersonalization类,标准的 WebPartManager控件在使用时已经修改,更新的WebPartManager控件见Listing 5.
Listing 5. AnonWebPartManager.vb

namespace myControls {
    using System.Web.UI.WebControls.WebParts;
    using System;
   
   
    // '' <summary>
    // '' Modifies the base WebPartManager control
    // '' to use the AnonWebPartPersonalization class
    // '' </summary>
    public class AnonWebPartManager : WebPartManager {
       
        protected override WebPartPersonalization CreatePersonalization() {
            return new AnonWebPartPersonalization(this);
        }
    }
}

 在Listing 5 中,使用定制的AnonWebPartPersonalization类覆盖WebPartManager控件的CreatePersonalization()方法
下一步就是开始准备使用Personalization个性化提供者,首先配置web.config.
Listing 6. Web.Config

<?xml version="1.0"?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
        <system.web>
                <anonymousIdentification enabled="True"/>
                <authentication mode="None" />
                <webParts>
                        <personalization defaultProvider="AnonProvider">
                                <providers>
                                        <add
            name="AnonProvider"
            type="myControls.AnonSqlPersonalizationProvider"
            connectionStringName="localSQLServer"/>
                                </providers>
                                <authorization>
          <allow users="Administrators" verbs="enterSharedScope"/>
                                </authorization>
                        </personalization>
                </webParts>
                </system.web>
</configuration>

Listing 6的 web.config 做了三件事,1、使用匿名ID,自动为每个用户一个产生GUID,储存在浏览器中。2、设置Authentication模式为None,让 authentication失效。3、缺省个性化提供者配置为AnonPersonalizationProvider。

 最后我们来测试Anonymous Personalization Provider。
Listing 7. TestAnonymous.aspx

<%@ Page Language="VB" %>
<%@ Register TagPrefix="custom" Namespace="myControls" %>
<%@ Register TagPrefix="user" TagName="PersonalizationManager"
   Src="~/PersonalizationManager.ascx" %>
<%@ Register TagPrefix="user" TagName="TextPart" Src="~/TextPart.ascx" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
   "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<script runat="server">

    Protected Sub Menu1_MenuItemClick(ByVal sender As Object, ByVal e As MenuEventArgs)
        WebPartManager1.DisplayMode = WebPartManager1.DisplayModes(e.Item.Text)
    End Sub

</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
    <style type="text/css">
        .personalizationManager
        {
            border:dotted 2px orange;
            padding:5px;
            background-color:White;
            font:12px Arial, Sans-Serif;
        }
        .personalizationManager span
        {
            padding-right:10px;
            margin-right:10px;
            border-right:solid 1px black;
        }
        .personalizationManager a
        {
            text-decoration:none;
        }
        .column
        {
            float:left;
            width:30%;
            height:200px;
            margin-right:10px;
            border:solid 1px black;
            background-color: white;
        }
        .menu
        {
            margin:5px 0px;
        }
        html
        {
            background-color:#eeeeee;
        }
    </style>
    <title>Anonymous Personalization</title>
</head>
<body>
    <form id="form1" runat="server">
    <custom:AnonWebPartManager
        id="WebPartManager1"
        Runat="server" />

    <user:PersonalizationManager
        id="PersonalizationManager1"
        runat="server" />

        <asp:Menu
            id="Menu1"
            OnMenuItemClick="Menu1_MenuItemClick"
            Orientation="Horizontal"
            CssClass="menu"
            Runat="server">
            <Items>
            <asp:MenuItem Text="Browse" />
            <asp:MenuItem Text="Design" />
            </Items>
        </asp:Menu>

        <asp:WebPartZone
            id="WebPartZone1"
            CssClass="column"
            Runat="server">
            <ZoneTemplate>
            <user:TextPart
                id="TextPart1"
                Title="Text Part"
                Description="Displays block of text"
                Runat="server" />
            </ZoneTemplate>
        </asp:WebPartZone>

        <asp:WebPartZone
            id="WebPartZone2"
            CssClass="column"
            Runat="server" />
    </form>
</body>
</html>

如果要模拟匿名用户,需要打开两种不同类型的浏览器,因为相同的浏览器要通用一个cookies。如用Default.aspx和Mozilla Firefox。
注意:
如果实验Anonymous Personalization Provider不成功,是因为匿名用户加到aspnet_Users数据库里,没有标记为匿名。为了解决这个问题需要执行 aspnet_PersonalizationPerUser_SetPageSettings存储过程。
EXEC dbo.aspnet_Users_CreateUser @ApplicationId, @UserName, 0, @CurrentTimeUtc, @UserId OUTPUT

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值