7 以人为本的Profile
7.1 使用Profile制作个性化页面
一个人性化的网站往往提供给用户很多个性化选择。比如让用户选择所喜欢的网站风格,让用户选择是否自动弹出消息提醒等。这些数据需要在用户把浏览器关闭后还能保存下来,因此只能选择数据库进行保存。对于登录过的用户比较好办,我们可以根据用户名和用户的选择存放在数据库中,对于非登录用户(匿名用户)怎么保存用户的选择呢?唯一的方法只能像Session那样分配给用户一个ID,把这个ID存放在Cookie中(当然也可以放在URL中),然后在数据库中保存这个ID相关的一些配置信息。
ASP.NET 2.0提供了Profile机制,能帮助我们完成类似的功能。Profile不仅仅支持登录用户还支持匿名用户,存储的数据也可以是任何可序列化类型。几乎无需写一行代码就能轻松实现用户个性化数据的保存。我们配置了一个Web.config文件,如下所示。
<?xml version="1.0"?>
<configuration>
<system.web>
<anonymousIdentification enabled="true"/>
<profile automaticSaveEnabled="true">
<properties>
<group name="UI">
<add name="ForeColor" defaultValue="Black" allowAnonymous="true" type="string"/>
<add name="EnableBold" defaultValue="false" allowAnonymous="true" type="bool"/>
</group>
<group name="UserInfo">
<add name="UserName" defaultValue="" allowAnonymous="false" type="string"/>
<add name="UserAge" defaultValue="0" allowAnonymous="false" type="int"/>
</group>
</properties>
</profile>
<compilation debug="true"/>
<authentication mode="Forms"/>
</system.web>
</configuration>
· <anonymousIdentification enabled="true"/>表示对匿名用户也启用Profile,系统会给匿名用户分配一个随机字符串组成的ID。
· <profile automaticSaveEnabled="true">表示自动在页面请求结束的时候保存Profile的设置到数据库中。
· <properties>中就是正式定义Profile的格式了,我们使用<group>标签把Profile分成了两组,<group name="UI">和<group name="UserInfo">。
· 在每一个<group>中的才是真正的Profile。name表示Profile的名字,defaultValue表示默认值,allowAnonymous表示匿名用户是否可以使用,type表示数据类型。
· <authentication mode="Forms"/>表示为系统启用了表单认证(这是ASP.NET认证方式的一种,以后的章节中会详细介绍),
然后,我们为页面添加一些控件来个性化页面。
n 文字颜色:
<asp:DropDownList ID="ddl_TextColor" runat="server">
<asp:ListItem Selected="True">Black</asp:ListItem>
<asp:ListItem>Blue</asp:ListItem>
<asp:ListItem>Red</asp:ListItem>
</asp:DropDownList>
<asp:CheckBox ID="cb_IsBlod" runat="server" Text="粗体" />
<br />
<asp:Button ID="btn_SaveSettings" runat="server" Text="保存个性化设置" OnClick=
"btn_SaveSettings_Click" />
<asp:Button ID="btn_Login" runat="server" OnClick="btn_
Login_Click" Text="登录" /><br />
<asp:Label ID="lab_Text" runat="server" Font-Names="黑
体" Font-Size="50pt" Height="77px" Text="编程快乐" Width=
"293px"></asp:Label>
效果如图12-24所示。
通过下拉框我们可以设置文字的颜色为黑色、蓝色或者红色,通过复选框我们可以设置文字是否是粗体。单击“保存个性化设置”按钮保存设置。
protected void btn_SaveSettings_Click(object sender, EventArgs e)
{
Profile.UI.ForeColor = ddl_TextColor.SelectedValue;
Profile.UI.EnableBold = cb_IsBlod.Checked;
ApplyUISettings();
}
看到这里读者会不会很惊讶,我们仅仅在Web.config文件中配置了Profile的信息,怎么在代码中就直接能访问到强类型的Profile了呢?其实,系统会在App_Code下生成临时的代码文件,如图12-25所示。
图12-25 系统生成的临时代码文件
在这里我们又自定义了一个ApplyUISettings()方法来向页面中的标签应用样式。
private void ApplyUISettings()
{
lab_Text.ForeColor = Color.FromName(Profile.UI.ForeColor);
lab_Text.Font.Bold = Profile.UI.EnableBold;
ddl_TextColor.SelectedValue = Profile.UI.ForeColor;
cb_IsBlod.Checked = Profile.UI.EnableBold;
}
同时为了保证页面首次加载的时候也能按照用户的个性化配置来显示,我们在Page_Load()的时候也需要应用配置。
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ApplyUISettings();
}
}
现在打开页面,并把样式设置为蓝色文字,粗体显示,如图12-26所示。
首次操作的时候比较慢,因为系统正在为你生成保存信息的数据库。默认是使用SQL Express数据库,文件就放在网站的App_Data文件夹下,如图12-27所示。
图12-26 保存自己的个性化设置 图12-27 App_Data下的ASPNETDB数据库文件
关闭页面后再打开,可以发现页面仍然保持了原来的样式设置。你可能会问,系统怎么知道我们还是原来的那个用户呢?其实,系统为匿名用户生成了一个ID字符串保存于Cookie中,页面加载的时候根据这个ID从数据库中读出数据填充Profile。在测试了匿名用户的Profile后,我们来为登录按钮添加Click事件处理方法。
protected void btn_Login_Click(object sender, EventArgs e)
{
FormsAuthentication.SetAuthCookie("test", false);
Response.Redirect(Request.Path);
}
在这里,我们假设一个名为test的用户登录了系统,并把页面重定向到本页。然后,我们在页面上添加一个PlaceHolder控件,在其中放置一些控件让用户输入Profile的信息和退出登录。
<asp:PlaceHolder ID="ph_UserInfo" runat="server">
姓名:<asp:TextBox ID="tb_Name" runat="server"></asp:TextBox>
年龄:<asp:TextBox ID="tb_Age" runat="server"></asp:TextBox>
<br />
<asp:Button ID="btn_SaveUserInfo" runat="server" Text="保存用户信息" OnClick=
"btn_SaveUserInfo_Click" />
<asp:Button ID="btn_Logout" runat="server" OnClick="btn_Logout_Click" Text="退
出" />
</asp:PlaceHolder>
保存用户信息按钮Click事件实现如下:
protected void btn_SaveUserInfo_Click(object sender, EventArgs e)
{
Profile.UserInfo.UserName = tb_Name.Text;
Profile.UserInfo.UserAge = int.Parse(tb_Age.Text);
GetUserInfo();
}
这里的GetUserInfo用于显示用户的信息(登录用户的信息和非登录用户的信息)。
private void GetUserInfo()
{
if (User.Identity.IsAuthenticated)
{
ph_UserInfo.Visible = true;
Response.Write("当前登录用户:" + User.Identity.Name + "<br/>");
Response.Write("Profile关联用户:" + Profile.UserName + "<br/>");
Response.Write("Profile.UserInfo.UserName:" + Profile.UserInfo.UserName +
"<br/>");
Response.Write("Profile.UserInfo.UserAge:" + Profile.UserInfo.UserAge +
"<br/>");
}
else
{
ph_UserInfo.Visible = false;
Response.Write("Profile关联用户:" + Profile.UserName + "<br/>");
}
}
退出登录按钮Click事件实现如下:
protected void btn_Logout_Click(object sender, EventArgs e)
{
FormsAuthentication.SignOut();
Profile.UserInfo.UserAge = 0;
Profile.UserInfo.UserName = "";
Response.Redirect(Request.Path);
}
同时,我们修改一下Page_Load,让页面首次加载的时候也显示用户信息。
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ApplyUISettings();
GetUserInfo();
}
}
再次打开页面,如图12-28所示。
我们看到,对于匿名用户来说,Profile.UserName属性为一个随机字符串,单击“登录”按钮后如图12-29所示。
图12-28 匿名用户关联了一个随机字符串作为ID 图12-29 单击登录按钮后显示用户信息
现在可以看到Profile关联的用户UserName已经为登录的test用户了。现在,我们把姓名设置为“小朱”,年龄设置为24,单击“保存用户信息”按钮。然后把样式修改为红色粗体,单击“保存个性化设置”按钮。如图12-30所示。
n 如果你现在关闭窗口再重新打开就会发现个性化设置还是原来在匿名状态下保存的蓝色粗体。因此现在已经不在登录状态了,比较一下发现现在的ID和上次的ID还是一样的。再次单击“登录”按钮后,页面又加载了test用户的个性化设置。
7.2 Profile总结
Profile的知识远远不止这些,我们这里仅仅对它进行了简单的介绍,在结束以前我们以第一节中的几个问题结束对Profile的讨论。
· 存储的物理位置。客户端Cookie/URL和服务器数据库。
· 存储的类型限制。可序列化类型。
· 状态使用的范围。当前请求的上下文,对每一个用户独立。
· 存储的大小限制。任意大小,读取写入频繁的数据不建议存入Profile。
· 生命周期。与关联的Cookie的生命周期一样。
· 安全与性能。数据总是存储在服务端,安全性比较高,但不易存储过多数据。
· 优缺点与注意事项。可以很方便地保存用户(匿名用户和已登录用户)的设置。