Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Beginning ASP.NET 2.0 With CSharp (2006) [eng]

.pdf
Скачиваний:
75
Добавлен:
16.08.2013
Размер:
20.33 Mб
Скачать

Chapter 11

Profiles in Wrox United

When it comes to employing profiles in a live site, you need first to create a definition for the profile properties, and then a page where you can add and edit the items in a user profile. On the Wrox United site, this is controlled on the Fan Club page, so take a look at how this page is constructed.

Earlier in this chapter, you built the skeleton for the FanClub.aspx page and made use of the <asp:LoginView> control to display different content depending on who is logged in to the page. In this Try It Out, you build on the code from earlier. You add code to the FanClub.aspx page, and use some settings from the Web.config file so that you can store details about each user in their profile.

Try It Out

Using Profiles in Wrox United

1.Open the Web.config file from the root of the Chapter 11 version of the Wrox United application. Look at the bottom of the code and you will see the following:

<!--

Define the user profile properties -->

<profile enabled=”true”> <properties>

<add name=”MemberName”/> <add name=”Name”/>

<add name=”Address”/> <add name=”City”/> <add name=”County”/> <add name=”PostCode”/>

<add name=”Country”/>

<add name=”Mailings” type=”System.Boolean”/> <add name=”Email”/>

<add name=”Theme”/>

<add name=”Cart” serializeAs=”Binary” type=”Wrox.Commerce.ShoppingCart” allowAnonymous=”true”/>

</properties>

</profile>

</system.web>

</configuration>

In the profile definition for Wrox United, you have specified that users can store their name, address details, whether they would like to receive mailings from the site, their e-mail address, and their favorite theme for the site. There is also a Cart property, which is used each time the user wants to purchase items from the store.

2.Add some code to the FanClub.aspx page so that users can both store new profile properties and view or edit existing properties. Open the page and add the following highlighted lines of code (there’s quite a lot of code to add, but as you’ll see, all you’ll be doing is adding controls to the page and laying them out in a table):

<asp:LoginView ID=”FCLoginView” Runat=”server” OnViewChanged=”FCLoginView_ViewChanged”>

<RoleGroups>

<asp:RoleGroup Roles=”FanClubMember”> <ContentTemplate>

<p>

408

Roles and Profiles

Welcome back

<asp:LoginName ID=”FCLoginName” runat=”server” />

.</p>

<p>

There are always lots of exciting things happening with the fan club,

...

set, but keep your eyes on your inbox for more details. </p>

<h3>

User Settings</h3> <p>

Your user details are shown below.</p> <asp:ChangePassword ID=”ChangePassword1” runat=”server”> </asp:ChangePassword>

<br />

<table border=”0”> <tr>

<td>Name:</td>

<td><asp:TextBox ID=”txtName” runat=”server” Columns=”30” /> <asp:RequiredFieldValidator ID=”rfv1” runat=”server” ControlToValidate=”txtName”

Text=”*” ErrorMessage=”You must enter a value for your name” /> </td>

</tr><tr>

<td>Address:</td>

<td><asp:TextBox ID=”txtAddress” runat=”server” Columns=”25” Rows=”5” TextMode=”multiLine” />

<asp:RequiredFieldValidator ID=”RequiredFieldValidator1” runat=”server” ControlToValidate=”txtAddress” Text=”*” ErrorMessage=”You must enter a value for the address” />

</td>

</tr><tr>

<td>City:</td>

<td><asp:TextBox ID=”txtCity” runat=”server” /> <asp:RequiredFieldValidator ID=”RequiredFieldValidator2” runat=”server” ControlToValidate=”txtCity”

Text=”*” ErrorMessage=”You must enter a value for the city” /> </td>

</tr><tr>

<td>County:</td>

<td><asp:TextBox ID=”txtCounty” runat=”server” /> <asp:RequiredFieldValidator ID=”RequiredFieldValidator3” runat=”server” ControlToValidate=”txtCounty”

Text=”*” ErrorMessage=”You must enter a value for the county” /> </td>

</tr><tr>

<td>Postcode:</td>

<td><asp:TextBox ID=”txtPostCode” runat=”server” /> <asp:RequiredFieldValidator ID=”RequiredFieldValidator4” runat=”server” ControlToValidate=”txtPostCode” Text=”*” ErrorMessage=”You must enter a value for the post code” />

</td>

</tr><tr>

<td>Country:</td>

<td><asp:TextBox ID=”txtCountry” runat=”server” />

409

Chapter 11

<asp:RequiredFieldValidator ID=”RequiredFieldValidator5” runat=”server” ControlToValidate=”txtCountry” Text=”*” ErrorMessage=”You must enter a value for the country” />

</td>

</tr><tr>

<td>Subscribe to email updates:</td>

<td><asp:CheckBox ID=”chkMailing” runat=”server” /></td> </tr><tr>

<td>Email:<br /></td>

<td><asp:TextBox ID=”txtEmail” runat=”server” /> <asp:RequiredFieldValidator ID=”RequiredFieldValidator6” runat=”server” ControlToValidate=”txtEmail”

Text=”*” ErrorMessage=”You must enter a value for the email” /> <asp:RegularExpressionValidator ID=”rev1” runat=”server” ControlToValidate=”txtEmail”

ValidationExpression=”\w+([-+.’]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*” Text=”*” ErrorMessage=”Please enter a valid email address” />

</td>

</tr><tr>

<td>Membership Alias:</td>

<td><asp:TextBox ID=”txtAlias” runat=”server” /> <asp:RequiredFieldValidator ID=”RequiredFieldValidator7” runat=”server” ControlToValidate=”txtAlias” Text=”*” ErrorMessage=”You must enter a value for the membership alias” />

</td>

</tr>

</table> <br />

<asp:ValidationSummary ID=”vs” runat=”server” DisplayMode=”BulletList” /> <br />

<asp:Button ID=”btnSaveChanges” runat=”server” OnClick=”btnSaveChanges_Click” Text=”Save Changes” />

<asp:Button ID=”btnCancelChanges” runat=”server” OnClick=”btnCancelChanges_Click” CausesValidation=”false” Text=”Cancel Changes” />

</ContentTemplate>

</asp:RoleGroup>

...

</RoleGroups>

...

</asp:LoginView>

3.You also need to add code to the FanClub.aspx.cs file so that the btnSaveChanges and btnCancelChanges buttons have event handlers that will run code each time they are clicked. Right-click FanClub.aspx and select View Code, and then add the following highlighted methods to the FanClub.aspx.cs file:

using System; using System.Web;

using System.Web.UI.WebControls;

partial class FanClub : System.Web.UI.Page

{

410

Roles and Profiles

private void Page_Load(object sender, System.EventArgs e)

{

 

if (!Page.IsPostBack)

 

DisplayProfileProperties();

 

}

 

protected void btnCancelChanges_Click( object sender,

System.EventArgs e)

{

 

DisplayProfileProperties();

 

}

 

protected void btnSaveChanges_Click( object sender, System.EventArgs e)

{

 

Profile.Name = ((TextBox)FCLoginView.FindControl(“txtName”)).Text;

Profile.Address = ((TextBox)FCLoginView.FindControl(“txtAddress”)).Text;

Profile.City = ((TextBox)FCLoginView.FindControl(“txtCity”)).Text;

Profile.County = ((TextBox)FCLoginView.FindControl(“txtCounty”)).Text;

Profile.PostCode = ((TextBox)FCLoginView.FindControl(“txtPostCode”)).Text;

Profile.Country = ((TextBox)FCLoginView.FindControl(“txtCountry”)).Text;

Profile.Mailings = ((CheckBox)FCLoginView.FindControl(“chkMailing”)).Checked;

Profile.Email = ((TextBox)FCLoginView.FindControl(“txtEmail”)).Text;

Profile.MemberName = ((TextBox)FCLoginView.FindControl(“txtAlias”)).Text;

Server.Transfer(SiteMap.CurrentNode.Url);

 

}

 

protected void FCLoginView_ViewChanged( object sender,

System.EventArgs e)

{

 

DisplayProfileProperties();

 

}

 

private void DisplayProfileProperties()

{

TextBox NameBox = (TextBox)FCLoginView.FindControl(“txtName”);

if (NameBox != null)

{

((TextBox)FCLoginView.FindControl(“txtName”)).Text = Profile.Name; ((TextBox)FCLoginView.FindControl(“txtAddress”)).Text = Profile.Address; ((TextBox)FCLoginView.FindControl(“txtCity”)).Text = Profile.City; ((TextBox)FCLoginView.FindControl(“txtCounty”)).Text = Profile.County; ((TextBox)FCLoginView.FindControl(“txtPostCode”)).Text = Profile.PostCode; ((TextBox)FCLoginView.FindControl(“txtCountry”)).Text = Profile.Country; ((CheckBox)FCLoginView.FindControl(“chkMailing”)).Checked = Profile.Mailings; ((TextBox)FCLoginView.FindControl(“txtEmail”)).Text = Profile.Email; ((TextBox)FCLoginView.FindControl(“txtAlias”)).Text = Profile.MemberName;

}

}

}

4.Run the site again and log in as Lou, password lou@123. Go to the home page for the Fan Club and you will see what is shown in Figure 11-17 at the bottom of the page.

411

Chapter 11

Figure 11-17

5.Enter some details and click the Save Changes button. If you log out and log back in again, you’ll see that the information is saved, as shown in Figure 11-18.

412

Roles and Profiles

Figure 11-18

How It Works

The Web.config file contains the definition for each of the profile properties employed in the Wrox United application. These include (among others) the name of the user, the address, and the e-mail address. The capability to store data for each user in a profile is controlled by the code in the

FanClub.aspx page.

When users update their profile by clicking the Save Changes button, the following code is run:

protected void btnSaveChanges_Click( object sender, System.EventArgs e)

{

Profile.Name = ((TextBox)FCLoginView.FindControl(“txtName”)).Text; Profile.Address = ((TextBox)FCLoginView.FindControl(“txtAddress”)).Text; Profile.City = ((TextBox)FCLoginView.FindControl(“txtCity”)).Text; Profile.County = ((TextBox)FCLoginView.FindControl(“txtCounty”)).Text; Profile.PostCode = ((TextBox)FCLoginView.FindControl(“txtPostCode”)).Text; Profile.Country = ((TextBox)FCLoginView.FindControl(“txtCountry”)).Text; Profile.Mailings = ((CheckBox)FCLoginView.FindControl(“chkMailing”)).Checked; Profile.Email = ((TextBox)FCLoginView.FindControl(“txtEmail”)).Text; Profile.MemberName = ((TextBox)FCLoginView.FindControl(“txtAlias”)).Text; Server.Transfer(SiteMap.CurrentNode.Url);

}

413

Chapter 11

This code looks quite messy, and this is because of one very good reason. You’ve chosen to display these controls only on one view of the page using the LoginView control. Here’s the syntax for storing just the name:

Profile.Name = ((TextBox)FCLoginView.FindControl(“txtName”)).Text;

The syntax used to essentially say “TextBox.Text” means “find me the control called txtName, and when you find it, treat it like a TextBox control, and then grab the data stored in its Text property and use that value to store in the profile.” The similar syntax used against the Mailings profile property demonstrates this slightly differently:

Profile.Mailings = ((CheckBox)FCLoginView.FindControl(“chkMailing”)).Checked;

This time around, it’s a case of “find me a control called chkMailing, treat it as a CheckBox control, and set the Mailings property of the profile to the value of the Checked property of the CheckBox.”

After the profile has been populated with data, the code will then call a method, the Server.Transfer method, which will run the code that would run if the specified page were requested:

Server.Transfer(SiteMap.CurrentNode.Url);

The Server.Transfer() method stops the current page from executing, and runs the content on the specified page, which in this case is like reloading the current page again to refresh the current view of the page.

At several points in the page life cycle, the display of the profile properties is updated. For example, each time the view of the Fan Club changes, the following code is run:

protected void FCLoginView_ViewChanged( object sender, System.EventArgs e)

{

DisplayProfileProperties();

}

This calls the following method:

private void DisplayProfileProperties()

{

TextBox NameBox = (TextBox)FCLoginView.FindControl(“txtName”);

if (NameBox != null)

{

((TextBox)FCLoginView.FindControl(“txtName”)).Text = Profile.Name; ((TextBox)FCLoginView.FindControl(“txtAddress”)).Text = Profile.Address; ((TextBox)FCLoginView.FindControl(“txtCity”)).Text = Profile.City; ((TextBox)FCLoginView.FindControl(“txtCounty”)).Text = Profile.County; ((TextBox)FCLoginView.FindControl(“txtPostCode”)).Text = Profile.PostCode; ((TextBox)FCLoginView.FindControl(“txtCountry”)).Text = Profile.Country; ((CheckBox)FCLoginView.FindControl(“chkMailing”)).Checked = Profile.Mailings; ((TextBox)FCLoginView.FindControl(“txtEmail”)).Text = Profile.Email; ((TextBox)FCLoginView.FindControl(“txtAlias”)).Text = Profile.MemberName;

}

}

414

Roles and Profiles

The convoluted syntax for retrieving the value of each control should be a bit more familiar from the code used earlier in this How It Works section, but there’s one addition here. Notice that there is a test to see if the txtName text box exists on the currently visible version of the page:

TextBox NameBox = (TextBox)FCLoginView.FindControl(“txtName”);

if (NameBox != null)

{

So, if the txtName text box is visible (which it will be if the user is logged in as a member of the FanClubMember role), then the profile data is retrieved. If the user is anonymous, or is a member of other roles (and not the FanClubMember role), then the profile will not exist. To avoid errors at run-time, you don’t want to try to retrieve data that does not exist, so this check is essential (just try removing it and accessing the page as an anonymous user to see the mess if you’re not careful).

One last thing to consider before moving on — in the layout code (on FanClub.aspx), there were some controls that you may not be familiar with yet:

<table border=”0”> <tr>

<td>Name:</td>

<td><asp:TextBox ID=”txtName” runat=”server” Columns=”30” /> <asp:RequiredFieldValidator ID=”rfv1” runat=”server” ControlToValidate=”txtName”

Text=”*” ErrorMessage=”You must enter a value for your name” />

</td>

</tr><tr>

In the layout code, each TextBox control had a validation control next to it. In this example, the txtName TextBox had a RequiredFieldValidator control next to it, which will ensure that users fill in data for each of the required fields before saving profile changes. Essentially, the text box is marked as “Required,” as the validator’s name suggests. If no value is entered, there will be a small red asterisk displayed next to the text box.

You’ll learn more about validation controls in Chapter 15, where you can see how they are used to minimize data entry errors and protect your code from malicious user input.

So, you’ve stored some simple data in a user profile. If you want to know where exactly this data is stored, you will find it in the AspNetDB.mdf database. Take a look in the aspnet_Profiles table and you will see that data, similar to Figure 11-19, is stored in your database.

In Figure 11-19, you can see that the Lou profile currently has some properties set, as you specified in the example. You will not need (or want) to edit this data, but it’s useful to know where it’s stored.

415

Chapter 11

Figure 11-19

Storing Preferences

There’s one last example that you can play with in this chapter, and that goes way back to the discussions you will recall from Chapter 5. In that chapter, along with page styling and CSS, you learned the concept of storing layout and style preferences in themes. These themes can be switched on a page-by-page basis as was discussed in that chapter. However, you can also store data about which theme a user may prefer to use for a site in a user profile, enabling users to personalize their viewing experience a bit more. In the following Try It Out, you have a go at including this functionality in the Wrox United application.

Try It Out

Storing Theme Preference in Profiles

1.Add the following highlighted lines of code to the FanClub.aspx page:

</tr><tr>

<td>Membership Alias:</td>

<td><asp:TextBox ID=”txtAlias” runat=”server” /> <asp:RequiredFieldValidator ID=”RequiredFieldValidator7”

runat=”server” ControlToValidate=”txtAlias” Text=”*” ErrorMessage=”You must enter a value for the membership alias” />

</td>

</tr>

<tr>

<td>Theme:</td>

<td><asp:DropDownList ID=”ThemeList” runat=”server”> <asp:ListItem Text=”Default” Value=”” /> <asp:ListItem Text=”Wrox Red” Value=”WroxRed” /> <asp:ListItem Text=”Wrox Blue” Value=”WroxBlue” />

</asp:DropDownList>

</td>

</tr>

416

Roles and Profiles

2.The other piece of the puzzle is to add some code to store and retrieve the theme preference from the user’s profile. Modify FanClub.aspx.cs to add the following highlighted lines of code to the btnSaveChanges_Click event handler:

protected void btnSaveChanges_Click( object sender, System.EventArgs e)

{

Profile.Theme =

((DropDownList)FCLoginView.FindControl(“ThemeList”)).SelectedValue; Profile.Name = ((TextBox)FCLoginView.FindControl(“txtName”)).Text; Profile.Address = ((TextBox)FCLoginView.FindControl(“txtAddress”)).Text; Profile.City = ((TextBox)FCLoginView.FindControl(“txtCity”)).Text; Profile.County = ((TextBox)FCLoginView.FindControl(“txtCounty”)).Text; Profile.PostCode = ((TextBox)FCLoginView.FindControl(“txtPostCode”)).Text; Profile.Country = ((TextBox)FCLoginView.FindControl(“txtCountry”)).Text; Profile.Mailings = ((CheckBox)FCLoginView.FindControl(“chkMailing”)).Checked; Profile.Email = ((TextBox)FCLoginView.FindControl(“txtEmail”)).Text; Profile.MemberName = ((TextBox)FCLoginView.FindControl(“txtAlias”)).Text; Server.Transfer(SiteMap.CurrentNode.Url);

}

3.Modify the DisplayProfileProperties method to include the code that will retrieve and display the currently stored value for the Theme property from the user’s profile:

private void DisplayProfileProperties()

{

TextBox NameBox = (TextBox)FCLoginView.FindControl(“txtName”);

if (NameBox != null)

{

((DropDownList)FCLoginView.FindControl(“ThemeList”)).SelectedValue =

Profile.Theme; ((TextBox)FCLoginView.FindControl(“txtName”)).Text = Profile.Name;

((TextBox)FCLoginView.FindControl(“txtAddress”)).Text = Profile.Address; ((TextBox)FCLoginView.FindControl(“txtCity”)).Text = Profile.City; ((TextBox)FCLoginView.FindControl(“txtCounty”)).Text = Profile.County; ((TextBox)FCLoginView.FindControl(“txtPostCode”)).Text = Profile.PostCode; ((TextBox)FCLoginView.FindControl(“txtCountry”)).Text = Profile.Country; ((CheckBox)FCLoginView.FindControl(“chkMailing”)).Checked = Profile.Mailings; ((TextBox)FCLoginView.FindControl(“txtEmail”)).Text = Profile.Email; ((TextBox)FCLoginView.FindControl(“txtAlias”)).Text = Profile.MemberName;

}

At this stage, you’ve added all the required code to store the preference. The thing that’s missing is the ability to actually switch the theme on the pages on the site.

4.Right-click the App_Code folder and add a new item. Select Class from the list of available templates, and call it ThemeModule.cs, as shown in Figure 11-20.

417