Visual CSharp 1002005 A Developers Notebook [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Visual CSharp 1002005 A Developers Notebook [Electronic resources] - نسخه متنی

Jesse Liberty

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
توضیحات
افزودن یادداشت جدید









4.4. Create Personalized Web Sites



Modern web sites that are designed to be visited by users
repeatedly should support personalization for
those users. Personalization enables the site to remember the
user's preferences and, if appropriate, previous
user choices (for example, "You have three items in
your shopping cart.")


Tip: ASP.NET provides extensive support for personalization, allowing your
site to "remember" your
user's preferences.

4.4.1. How do I do that?



To get started, you'll want a new project that
duplicates the work you accomplished in the previous lab. Here are
the steps you need to take:



Create a new web site and name it
SitePersonalization.



On the Visual Studio menu bar, choose Website
Copy Website and click
the Connect to Website button. The relevant part of the page is shown
in Figure 4-28.




Figure 4-28. Connecting to a remote site





Point to the previous lab and click Open. The wizard uses a question
mark to identify the files that have the same name in both
applications. Highlight all the files in the remote site, and then
click the left-pointing arrow, as shown in Figure 4-29.




Figure 4-29. Copying all files from the remote web site to the source web site





Close the wizard and, if prompted, click Yes to overwrite files and
Yes to update files.


Tip: If you did not create the previous lab, you can access the files by
downloading the source code and copying it from the
SecurityRoles folder.



Run the program to make sure you have a duplicate of your previous
lab.



The simplest form of
personalization
is to record information about the user, and then to make that
information available whenever the user logs on. This requires a kind
of persistence that goes beyond session
state. To create true personalization, you'll want
to store the user's choices and information in a
database that associates the saved information with a particular
user, and that persists indefinitely.


ASP.NET 2.0 provides all the plumbing
required. You do not have to design, edit, or manage the database
tables; all of that is done for you.


ASP.NET 2.0 has decoupled the Profile API (how you programmatically
interact with profile data) from the underlying data provider (how
you store the data). This allows you to use the default provider (SQL
Server Express), or one of the other providers supplied (SQL Server),
or even to write your own provider (for example, for an existing
customer relationship management system), without changing the way
you interact with the profile in the rest of your code.


To add data to the
user's profile, first you must alert the system
about the data you want to store. You do so in
Web.config by adding a profile section to the
system.web element:


<?xml version="1.0"?>
<configuration>
<connectionStrings>
<remove name="LocalSqlServer" />
<add name="LocalSqlServer"
connectionString="data source=.\sqlexpress;Integrated
Security=SSPI;Initial Catalog=aspnetdb" />
</connectionStrings>
<system.web>
<membership defaultProvider="AspNetSqlMembershipProvider" />
<authentication mode="Forms"/>
<roleManager enabled="True" defaultProvider="AspNetSqlRoleProvider" />
<compilation debug="true"/>
<profile>
<properties>
<add name="lastName" />
<add name="firstName" />
<add name="phoneNumber" />
<add name="birthDate" type="System.DateTime"/>
</properties>
</profile>
</system.web>
</configuration>


This causes the Profile API to create storage for four pieces of
information: first and last name, phone number, and birth date. The
default storage type is string. Notice, however,
that we are storing the birth date as a DateTime
object.


You can gather this information in any way you want. To keep the
example simple, we'll remove the role groups section
from
Default.aspx and add a new hyperlink
to LoggedInTemplate:


<asp:LoginView ID="LoginView1" Runat="server">
<LoggedInTemplate>
Welcome
<asp:LoginName ID="LoginName1" Runat="server" />
<asp:HyperLink ID="linkProfile" Runat="server"
NavigateUrl="~/ProfileInfo.aspx">Add Profile Info
</asp:HyperLink>
...
</LoggedInTemplate>
...
</asp:LoginView>


As you can see, the link brings you to
ProfileInfo.aspx, a page you'll
create now. Add a table, and within the table add labels and
checkboxes as well as a Save button, as shown in Figure 4-30.




Figure 4-30. The Profile table




The HTML code for the Profile table is shown in Example 4-3.



Example 4-3. HTML for the Profile table



<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="ProfileInfo.aspx.cs"
Inherits="ProfileInfo_aspx" %>
<!DOCTYPE html PUBLIC "-
//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/
DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Profile Information</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<table>
<tr>
<td>First Name: </td>
<td style="width: 193px">
<asp:TextBox ID="firstName" Runat="server" />
</td>
</tr>
<tr>
<td>Last Name: </td>
<td style="width: 193px">
<asp:TextBox ID="lastName" Runat="server" /></td>
<!-- <td>
<asp:RequiredFieldValidator ID="lastNameRequired" Runat="server"
ErrorMessage="Last name is required"
ControlToValidate="lastName" Display="Dynamic">
*</asp:RequiredFieldValidator>
</td>
-->
</tr>
<tr>
<td>Phone number: </td>
<td style="width: 193px">
<asp:TextBox ID="phone" Runat="server" />
</td>
</tr>
<tr>
<td>BirthDate</td>
<td style="width: 193px"><asp:TextBox ID="birthDate"
Runat="server" /></td>
</tr>
<tr>
<td>
<asp:Button ID="save" Text="Save" Runat="server"
OnClick="save_Click" />
</td>
<td style="width: 193px"></td>
</tr>
</table>
</div>
&nbsp;
</form>
</body>
</html>


All you have to do now is add an event handler
for the Save button:


void save_Click(object sender, EventArgs e)
{
if (Profile.IsAnonymous = = false)
{
Profile.lastName = this.lastName.Text;
Profile.firstName = this.firstName.Text;
Profile.phoneNumber = this.phone.Text;
Profile.birthDate = Convert.ToDateTime(this.birthDate.Text);
}
Response.Redirect("Default.aspx");
}


When you start the application, you are asked to log in. Once you do
this, a new hyperlink, Add Profile Info
appears. This was created by the hyperlink
you added to LoggedInTemplate (earlier). Clicking
that link brings you to your new Profile page.


The Profile object has properties that correspond to
the properties you added in Web.config. To test
that the Profile object has in fact stored this
data, you'll add a panel to the bottom of the
default page, after the hyperlinks but before the closing
</div> tag:


<asp:Panel ID="pnlInfo" 
Runat="server" Visible="False" Width="422px" Height="63px">
<br />
<table width="100%">
<tr>
<td>
<asp:Label ID="lblFullName" Runat="server"
Text="Full name unknown">
</asp:Label></td>
</tr>
<tr>
<td>
<asp:Label ID="lblPhone" Runat="server"
Text="Phone number unknown">
</asp:Label>
</td>
</tr>
<tr>
<td>
<asp:Label ID="lblBirthDate" Runat="server"
Text="Birthdate unknown">
</asp:Label>
</td>
</tr>
</table>
</asp:Panel>


The panel has a table with three rows, and each row has a label that
is initialized to say that the value is unknown (this is not normally
needed, but it's included here to ensure that the
data you see was in fact retrieved from the
Profile object). When the page is loaded, you
check to see if you have profile data for this user and, if so, you
assign that data to the appropriate controls:


public partial class Default_aspx
{
public void Page_Load(object sender, EventArgs e)
{
if (Profile.UserName != null && Profile.IsAnonymous = = false)
{
this.lblFullName.Text = "Full name: " +
Profile.firstName + " " + Profile.lastName;
this.lblPhone.Text = "Phone: " + Profile.phoneNumber;
this.lblBirthDate.Text = "Born: " +
Profile.birthDate.ToShortDateString( );
this.pnlInfo.Visible = true;
}
else
{
this.pnlInfo.Visible = false;
}
} // end page load
} // end partial class


Notice that you convert DateTime to a
string for easy display in the label.


Run the application, log in, and click Add Profile Info. You will be
brought to the Profile Information form, as shown in Figure 4-31.




Figure 4-31. The Profile Information page




When you return to the default page, the Page_Load
event fires, both parts of the if statement return
true (that is, the UserName
value in the profile is not null), and the user is
logged in and thus is not anonymous:


if (Profile.UserName != null && Profile.IsAnonymous =  = false)


Your profile information is displayed, as shown in Figure 4-32.




Figure 4-32. Profile information displayed





4.4.2. What about...



...the profile information? Where is it stored?


To see where the profile information is
stored, stop the application and examine the tables in your storage
database. You'll want to examine two tables:
aspnet_Users (which lists all the users your security
system knows about) and
aspnet_Profile (which lists the profile information for
those users), as shown in Figure 4-33.




Figure 4-33. Examining the profile in the database




There are a number of things to notice. I've circled
the UserID in both tables; the entries in the
Profile table are matched to the individual user via the
UserID.


The Profile table has two significant columns
in addition to UserID:
PropertyNames and
PropertyValueString. The entries in the
PropertyNames columns correspond to the entries
you created in the
<profile> section of
Web.config:


<profile>
<properties>
<add name="lastName" />
<add name="firstName" />
<add name="phoneNumber" />
<add name="birthDate" type="System.DateTime"/>
</properties>
</profile>


Each property is named (for example, lastName) and
is given a type (S for string), a starting offset
(firstName begins at offset 7), and a length
(firstName's value has a length
of 5). This offset and value are used to find the value within the
PropertyValueString field.


...what about saving complex types?


So far you've seen how to save built-in types such
as strings and dates. In the next lab you'll see how
to store complex types that might be needed to create a
"shopping cart."


Note: Notice that birthDate is listed as a string that begins at
offset 24 and is 95 characters long, but if you look at the
PropertyValuesString column, you'll find that the
birth date is encoded as XML.

4.4.3. Where can I learn more?



O'Reilly's ONDotnet site
personalization and
extensive documentation on the subject
is available in the MSDN.



/ 71