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

Beginning ASP.NET 2

.0.pdf
Скачиваний:
20
Добавлен:
17.08.2013
Размер:
24.67 Mб
Скачать

Roles and Profiles

The list of profiles specified is actually the set of properties to be stored for all registered users of the Wrox United application. The default type of data to store is textual data (string data), so for those items without a specific type attribute, the data type is assumed to be string.

Two items on this list are not strings. The first is the Mailings property. This is a Boolean value (true or false) that can be used to store a simple choice — does the user want to receive e-mail concerning the current news about the club or not? You can control the input for this value on a web page by simply including a checkbox that the user can click as a simple yes or no response to a question. This is an example of using a standard .NET type, and you could equally add profile properties using different types, such as storing an age in an Integer, or a date of birth in a DateTime.

The other non-string data type being used in this case is a custom type called Wrox.Commerce.ShoppingCart. This type is explained in more detail in Chapter 13. For now, you should know that this type will store details of the current user’s shopping cart, so that if they fill the cart with items on one visit to the site, but choose not to purchase those items at that time, the data about the items stored in the cart will remain. In this way, when they next log in, the items are still in their cart. It also dictates whether anonymous users can fill a shopping cart. Because this is set to true, anyone coming to the site can fill a basket with items, so it’s up to you to make sure that you create a profile for them when they check out. You’ll come back to this point a bit later in this chapter in the section titled “Managing Anonymous Shopping Carts.”

A custom type is an object that has been defined by code to meet the requirements of a specific scenario. The code is contained in a class that has been developed to describe the properties and methods available to objects based on that particular type definition. For example, a String object has a ToString() method, but a DateTime object has ToString(), ToShortDateString, and

ToLongDateString() methods, among others. You can write a custom type, like the ShoppingCart in this example, that has a specific set of properties and methods available, so a ShoppingCart object will have an Update() method and a SubTotal() method.

To store some data in a profile, the following syntax can be used in a code file for a web page:

Profile.Name = “Chris Hart”

Or, similarly, you can use this syntax to use a value entered by a user to populate the Name information in the Profile:

Profile.Name = txtName.Text

This will cause the profile to store whatever the user has entered as the value of a text box on a page. So, to retrieve a value from a profile and display it on a page, you use the opposite syntax:

txtName.Text = Profile.Name

This is all quite simple, so the next section looks at it in context.

409

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 will 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 up the Web.config file from the root of the Chapter 11 version of the Wrox United application. Look down at the bottom of the code and you will see the following code:

<!--

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, their favorite theme for the site, and there is also a Cart property. The Cart property will be used each time the user wants to purchase items from the store.

2.The next step is to add some code to the FanClub.aspx page so that users can both store new profile properties and view or edit existing properties. Open up 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”>

410

Roles and Profiles

<ContentTemplate>

<p>

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>

411

Chapter 11

</tr><tr>

<td>Country:</td>

<td><asp:TextBox ID=”txtCountry” runat=”server” /> <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.vb 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, then add the following highlighted methods to the FanClub.aspx.vb file:

Partial Class FanClub

Inherits System.Web.UI.Page

412

Roles and Profiles

Private Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _ Handles Me.Load

If Not Page.IsPostBack Then

DisplayProfileProperties()

End If

End Sub

Sub btnCancelChanges_Click(ByVal sender As Object, ByVal e As System.EventArgs) DisplayProfileProperties()

End Sub

Sub btnSaveChanges_Click(ByVal sender As Object, ByVal e As System.EventArgs) Profile.Name = CType(FCLoginView.FindControl(“txtName”), TextBox).Text Profile.Address = CType(FCLoginView.FindControl(“txtAddress”), TextBox).Text Profile.City = CType(FCLoginView.FindControl(“txtCity”), TextBox).Text Profile.County = CType(FCLoginView.FindControl(“txtCounty”), TextBox).Text Profile.PostCode = CType(FCLoginView.FindControl(“txtPostCode”), TextBox).Text Profile.Country = CType(FCLoginView.FindControl(“txtCountry”), TextBox).Text Profile.Mailings = CType(FCLoginView.FindControl(“chkMailing”), _

CheckBox).Checked

Profile.Email = CType(FCLoginView.FindControl(“txtEmail”), TextBox).Text Profile.MemberName = CType(FCLoginView.FindControl(“txtAlias”), TextBox).Text Server.Transfer(SiteMap.CurrentNode.Url)

End Sub

Sub FCLoginView_ViewChanged(ByVal sender As Object, ByVal e As System.EventArgs) DisplayProfileProperties()

End Sub

Private Sub DisplayProfileProperties()

Dim NameBox As TextBox = CType(FCLoginView.FindControl(“txtName”), TextBox)

If Not (NameBox Is Nothing) Then

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

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

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

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

CType(FCLoginView.FindControl(“txtPostCode”), TextBox).Text = _

Profile.PostCode

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

CType(FCLoginView.FindControl(“chkMailing”), CheckBox).Checked = _

Profile.Mailings

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

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

End If

End Sub

End Class

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.

5.Now 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.

413

Chapter 11

Figure 11-17

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:

Sub btnSaveChanges_Click(ByVal sender As Object, ByVal e As System.EventArgs) Profile.Name = CType(FCLoginView.FindControl(“txtName”), TextBox).Text Profile.Address = CType(FCLoginView.FindControl(“txtAddress”), TextBox).Text Profile.City = CType(FCLoginView.FindControl(“txtCity”), TextBox).Text Profile.County = CType(FCLoginView.FindControl(“txtCounty”), TextBox).Text Profile.PostCode = CType(FCLoginView.FindControl(“txtPostCode”), TextBox).Text Profile.Country = CType(FCLoginView.FindControl(“txtCountry”), TextBox).Text Profile.Mailings = CType(FCLoginView.FindControl(“chkMailing”), _

CheckBox).Checked

Profile.Email = CType(FCLoginView.FindControl(“txtEmail”), TextBox).Text Profile.MemberName = CType(FCLoginView.FindControl(“txtAlias”), TextBox).Text Server.Transfer(SiteMap.CurrentNode.Url)

End Sub

414

Roles and Profiles

Figure 11-18

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 = CType(FCLoginView.FindControl(“txtName”), TextBox).Text

The yucky syntax used to essentially say “TextBox.Text” means “find me the control called txtName. When you find it, treat it like a TextBox control, 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 = CType(FCLoginView.FindControl(“chkMailing”), _

CheckBox).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.”

415

Chapter 11

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:

Sub FCLoginView_ViewChanged(ByVal sender As Object, ByVal e As System.EventArgs) DisplayProfileProperties()

End Sub

This calls the following method:

Private Sub DisplayProfileProperties()

Dim NameBox As TextBox = CType(FCLoginView.FindControl(“txtName”), TextBox)

If Not (NameBox Is Nothing) Then

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

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

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

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

CType(FCLoginView.FindControl(“txtPostCode”), TextBox).Text = _

Profile.PostCode

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

CType(FCLoginView.FindControl(“chkMailing”), CheckBox).Checked = _

Profile.Mailings

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

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

End If

End Sub

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:

Dim NameBox As TextBox = CType(FCLoginView.FindControl(“txtName”), TextBox)

If Not (NameBox Is Nothing) Then

So, if the txtName box is visible (which it will be if the user is logged in as a member of the FanClub Member 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 that happens if you’re not careful!).

416

Roles and Profiles

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 txt Name 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 meet validation controls in more detail 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.

Figure 11-19

417

Chapter 11

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 by hand, but it’s useful to know where it’s stored.

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>

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.vb to include the following highlighted lines of code to the btnSaveChanges_Click event handler:

Sub btnSaveChanges_Click(ByVal sender As Object, ByVal e As System.EventArgs) Profile.Name = CType(FCLoginView.FindControl(“txtName”), TextBox).Text Profile.Address = CType(FCLoginView.FindControl(“txtAddress”), TextBox).Text Profile.City = CType(FCLoginView.FindControl(“txtCity”), TextBox).Text Profile.County = CType(FCLoginView.FindControl(“txtCounty”), TextBox).Text Profile.PostCode = CType(FCLoginView.FindControl(“txtPostCode”), TextBox).Text Profile.Country = CType(FCLoginView.FindControl(“txtCountry”), TextBox).Text Profile.Mailings = CType(FCLoginView.FindControl(“chkMailing”), _

CheckBox).Checked

Profile.Email = CType(FCLoginView.FindControl(“txtEmail”), TextBox).Text Profile.MemberName = CType(FCLoginView.FindControl(“txtAlias”), TextBox).Text

418