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

Beginning ASP.NET 2

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

Roles and Profiles

Profile.Theme = CType(FCLoginView.FindControl(“ThemeList”), _

DropDownList).SelectedValue

Server.Transfer(SiteMap.CurrentNode.Url)

End Sub

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

CType(FCLoginView.FindControl(“ThemeList”), DropDownList).SelectedValue = _

Profile.Theme

End If

End Sub

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.vb, as shown in Figure 11-20.

Figure 11-20

419

Chapter 11

5.Enter the following code into the new Class file:

Imports Microsoft.VisualBasic

Imports System

Imports System.Web

Imports System.Web.UI

Namespace Wrox.Web.GlobalEvents

Public Class ThemeModule

Implements IHttpModule

Public Sub Dispose() Implements System.Web.IHttpModule.Dispose

End Sub

Public Sub Init(ByVal context As System.Web.HttpApplication) _

Implements System.Web.IHttpModule.Init

AddHandler context.PreRequestHandlerExecute, _

New EventHandler(AddressOf app_PreRequestHandlerExecute)

End Sub

Private Sub app_PreRequestHandlerExecute(ByVal Sender As Object, _

ByVal E As EventArgs)

HttpContext.Current.Trace.Write(“ThemeModule”, “app_PreRequestHandlerExecute”) Dim p As Page = TryCast(HttpContext.Current.Handler, Page)

If p IsNot Nothing Then

Dim pb As ProfileCommon = DirectCast(HttpContext.Current.Profile, _ ProfileCommon)

p.Theme = pb.Theme End If

End Sub

End Class

End Namespace

6.Save the file, then open up Web.config and add the following highlighted code, just below the

System.Web node:

<system.web>

<httpModules>

<add name=”Page” type=”Wrox.Web.GlobalEvents.ThemeModule”/> </httpModules>

7.Run the page once more and you will see that there is now a drop-down box (shown at the bottom of Figure 11-21) on the page enabling you to select different themes to store in your user profile.

420

Roles and Profiles

Figure 11-21

How It Works

In this example, you’ve extended the basic FanClub.aspx page so that users can store their preferred theme in their profile. This facility is available only to registered members of the Fan Club.

Amending the layout code was a simple process of adding a DropDownList control to the page:

<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>

The value for the theme is stored as a simple string of text in the user’s profile, and is set in the same way as any other profile setting:

Profile.Theme = CType(FCLoginView.FindControl(“ThemeList”), _

DropDownList).SelectedValue

421

Chapter 11

This code means “find me the ThemeList control, it’s a DropDownList, so get me its SelectedValue property.” In this case, the DropDownList control’s SelectedValue property will be whatever the Value property for the selected item is set to, so, for example, if the user selected the item with the text “Wrox Red,” the value stored would be WroxRed.

So, at this stage the profile has been updated with the user’s preference, but the last bit of this exercise gave the site the capability to apply the selected theme to each page. The technique used in this case was to use an HttpModule to do this.

An HttpModule contains code that is processed every time any page in an application is processed. The module can be enabled and disabled via the Web.config file.

The module code can handle events that are raised each time a page is requested.

In this case, the event that is intercepted is processed before the code on a page is processed, and the requested page’s theme can be changed to match the theme specified in the user’s profile.

This section of the code is getting to be quite advanced in terms of programming techniques. Don’t worry if you don’t fully understand how this works — you will encounter more code like this in Professional ASP.NET 2.0, so you can treat this as a taste of what you can expect when you start to unleash the full power of ASP.NET.

Take a look at the code in the HttpModule and see how it works:

Imports Microsoft.VisualBasic

Imports System

Imports System.Web

Imports System.Web.UI

Namespace Wrox.Web.GlobalEvents

Public Class ThemeModule

Implements IHttpModule

The first part of the code in the file imports a few useful namespaces that contain classes you’ll need later in the code. The ThemeModule class is configured to reside within the Wrox.Web.GlobalEvents namespace. Additionally, the ThemeModule class implements the IHttpModule interface, which turns this simple class into a class that can be used as an HttpModule, provided you then implement the required methods, because there are some specific methods that all HttpModules must implement in order to work correctly.

In this case, two methods have to be implemented: the Init() method and the Dispose() method. Here’s the Dispose() method first — because there’s nothing that you need to do in this method, the empty method signature will just sit there in the file not bothering anyone:

Public Sub Dispose() Implements System.Web.IHttpModule.Dispose

End Sub

422

Roles and Profiles

Notice that there’s a specific Implements keyword that specifies that this particular Dispose() method implements the required IHttpModule.Dispose method, as required by all HttpModules. Now compare that to the code in the Init() method:

Public Sub Init(ByVal context As System.Web.HttpApplication) _

Implements System.Web.IHttpModule.Init

AddHandler context.PreRequestHandlerExecute, _

New EventHandler(AddressOf app_PreRequestHandlerExecute)

End Sub

At the top of this method is an Implements statement (which has wrapped onto the next line in this printed book due to page width restriction). The Init() method in this case implements the IHttpModule.Init method as required.

The code within the method itself here is a bit tricky to grasp at first. There’s only one line to consider, which declares a new event handler. The event handler will run each time the current context is at the PreRequestHandlerExecute stage in the request life cycle — in plain English, that’s pretty early in the request stage! This line of code means that each time the appropriate event fires, you can add an event handler that will be processed. This event handler is the last method declared in the code:

Private Sub app_PreRequestHandlerExecute(ByVal Sender As Object, _

ByVal E As EventArgs)

Dim p As Page = TryCast(HttpContext.Current.Handler, Page)

If p IsNot Nothing Then

Dim pb As ProfileCommon = DirectCast(HttpContext.Current.Profile, _ ProfileCommon)

p.Theme = pb.Theme End If

End Sub

End Class

End Namespace

This last method handles that PreRequestHandlerExecute event. The first line in this method gets the currently requested page object so that you can interact with it:

Dim p As Page = TryCast(HttpContext.Current.Handler, Page)

Notice the TryCast method used here — this method attempts to cast the current Handler object to a Page object type, which means that if the requested item is a page, the cast will be successful and the p object will contain an object reference to the requested page. However, if the item requested is not a page, the cast fails, and the p object is set to NULL (or nothing in VB.NET terms).

423

Chapter 11

As long as the Page object exists (and is not set to Nothing), you can then try to apply the theme to the page by obtaining the current profile properties and using that profile’s Theme property:

If p IsNot Nothing Then

Dim pb As ProfileCommon = DirectCast(HttpContext.Current.Profile, _ ProfileCommon)

p.Theme = pb.Theme End If

Notice the DirectCast notation in this case, which will throw an exception if the attempted cast fails. The only case when this would happen would be if you disabled profiles in the Web.config file, which would surely make this example a bit pointless! The Theme property of the page is set, at the end of this method, to the value stored in the profile property called Theme.

Finally, there was a new section added to the Web.config file that enabled the HttpModule itself:

<system.web>

<httpModules>

<add name=”Page” type=”Wrox.Web.GlobalEvents.ThemeModule”/> </httpModules>

The <httpModule> section can be filled with many different modules that you may want to run; in this example, there is just one module — the ThemeModule. The ThemeModule class that was declared is added in the type attribute, along with the namespace that it resides in, so that .NET knows exactly which ThemeModule you want to run.

That’s about it for this example — it’s a tricky piece of code, but it’s a neat way to make themes switch instantly on pages, and to stay switched for all pages on a site, because the module will run for each requested page on a site.

Managing Anonymous Shopping Car ts

Earlier this chapter briefly mentioned the presence of the following profile property:

<profile enabled=”true”> <properties>

<add name=”MemberName”/>

...

<add name=”Cart” serializeAs=”Binary” type=”Wrox.Commerce.ShoppingCart”

allowAnonymous=”true”/>

The allowAnonymous flag that is stored against the Profile.Cart value for each user session indicates that anonymous users can have a shopping cart. In this case, users may visit the site and neglect to log on, or they may be completely new to the site. The user will then happily fill up a basket with items, so it will be up to you to handle either switching the cart to an existing user when they log in, or creating a new profile when the anonymous user logs in and transferring the cart to the newly created user when the user attempts to check out.

424

Roles and Profiles

There is code that handles this transition in the Global.asax file, which handles global events raised by the code. Here’s the code as it is used in the Wrox United application:

Public Sub Profile_OnMigrateAnonymous(ByVal Sender As Object, ByVal e As _

ProfileMigrateEventArgs)

‘ get the profile for the anonymous user

Dim anonProfile As ProfileCommon = Profile.GetProfile(e.AnonymousID)

‘ if they have a shopping cart, then migrate that to the authenticated user If anonProfile.Cart IsNot Nothing Then

If Profile.Cart Is Nothing Then

profile.Cart = New Wrox.Commerce.ShoppingCart() profile.Cart.Items.AddRange(anonProfile.Cart.Items)

End if

anonProfile.Cart = Nothing End If

ProfileManager.DeleteProfile(e.AnonymousID)

AnonymousIdentificationModule.ClearAnonymousIdentifier()

End Sub

This code is examined in far more detail in Chapter 13 when you see exactly how the whole shopping experience works, but it’s useful to understand that there are consequences that you need to understand when you log in as a user, and the transferring of a shopping cart from one profile to another is the most important, because none of the other properties can actually be set for anonymous users.

Summar y

This chapter delved deeper into the world of roles, and introduced the concept of user profiles for storing additional data about a user. The two technologies can sit happily side-by-side, and used together are a great way to control access to a site and for customizing the user experience.

In this chapter, you’ve had a chance to take more control over the access permitted to users on a fully functional web application. You’ve had a chance to

Show or hide resources to selected user roles.

Display different page content depending on which role views the page.

Display links to selected pages, but prompt the user for more credentials for authorization.

Store more information about users in their user profile.

Store different types of data in a user profile, including the user’s preference for site theme.

These techniques will be built upon in the upcoming chapters to form part of the shopping cart functionality built in to the Wrox United site.

425

Chapter 11

Exercises

1.Create a new user account called Admin, and make this user a member of all of the groups. Log in to the Wrox United site as Admin and test to see whether you can access all of the different pages in both the fan club and the administration section.

2.Remove the Admin user from any role other than the Administrator role and test the site again. Ensure that you can access the following pages:

Admin.aspx

EditNews.aspx

UpdateProducts.aspx

3.The Admin user has had a request by a reporter out in the field — he’s uploaded a score for a match, but the score has just changed! Unfortunately, the reporter’s laptop has run out of battery, so he’s asked the Admin to update the score for him. Make sure that the Admin user can update the score of a match.

4.Add a field to the user profile for the Wrox United application called DateOfBirth. Give this property a data type of System.DateTime. Add an input field to the FanClub.aspx page so that users can update their date of birth. Note that you will need to convert the value entered in a text box to a DateTime value when you save the data — you might want to try the DateTime.Parse() function for this purpose. To retrieve the data, use the

Profile.DateOfBirth.ToShortDateString() function.

426

12

Web Ser vices

Web services have been “the next great thing” for a little too long now. They were originally introduced as part of the .NET Framework in its first incarnation (although they have been present in Java for a lot longer). Web services are a method of making information available in a standardized way that could be accessed by any developer’s application over the Web. Web services can form a library or shared repository of information that could be anything from the latest weather forecast, a map of your local amenities, a mathematical function calculator, to the tracks and album cover of the CD that you just inserted into your CD-ROM drive. You should be aware, though, that a web service on its own isn’t an application. Web services aren’t rendered as web pages, or as executable files (.exe); they come completely shorn of a user interface. It’s up to you as a developer to use them and integrate them into your applications. They are there to save you time and effort by reducing code duplication.

They can be used in one of two ways. You can create a web service that is exposed to the Web, to share with other developers and other applications. Or you can search for a web service that can be added to your own application. (They are similar to plug-ins in that respect.) For example, if your application is a company web site and you want to include directions to company headquarters, rather than scan in a map, or attempt to hand-draw one in a graphics tool, why not use one of the web services that makes sections of maps available online?

The information contained in the web service is wrapped up as an XML document, so that worries about platform-specific concerns, such as whether you’re accessing them on an old Windows 98 machine or a turbo-powered Powerbook, simply evaporate. Web services aren’t really anything new either; components have been performing a similar trick for many years now. However, there are some crucial differences. Components had to be distributed by the developer, and they had to be downloaded and installed. These things alone meant that they tended to be tied to one platform. This isn’t true of web services. A key word that emphasises what web services offer is standard. Everything to do with web services is standardized: the method of transmission, the method used to wrap the web service up, the way the web service is defined, all have clear W3C standards associated with the technologies involved. And to make life much easier, all these standards are based on XML. So they’re quick and easy to download, and even easier to use.

Chapter 12

This chapter looks at the following:

Introducing web services

Consuming web services

What happens in the typical life cycle of a web service

Testing a web service

Discovering a web service

Creating and consuming an example web service that uses a parameter

Creating a proxy — the old way of doing things

Web service security

Looking at Web Services

So what’s holding them back? The introduction alluded to the fact that web services haven’t quite taken off in the way that was expected, and it’s true and there are probably several reasons for that, but none that should stop you from using them. One is that developers and businesses don’t like giving away their hard work for free. The truth is when businesses create a web service it usually isn’t for public consumption. It is for in-house usage only, and even if it is available for the public to use, it is likely to come at a price. On the flipside, with free web services, you have no guarantee that they will still be there in a week or a year’s time, so it’s no good basing a large application around them. So do you fork out for a web service and increase the cost of your application, or take a gamble that a particular service will still be in existence over the next few years? This dilemma isn’t easily remedied.

Second is lack of education. People are still largely unaware of what web services can offer. I recently worked on a customer services application, which had to integrate with an existing contacts manager application and detect when the contacts manager was running and if it had loaded the latest customer information correctly. Rather than use a web service to make this information available, the client chose instead to write to the clipboard (especially awkward considering the users themselves might also be using the clipboard) and then my application had to periodically check the clipboard for the text to indicate that the contacts manager was running. As a result the application was twenty times more complicated than it needed to be.

Third is the lack of a single killer application. Before you started this chapter, could you name five common examples of web services? The problem is that they’re too good at the job they do, so they become practically invisible. Where is the Google or Internet Explorer of web services? I don’t know, but I might just be using it unwittingly. A good web service should dovetail seamlessly into your application, and your user should never know it’s there.

Last is the apparent learning curve required. With web services it’s easy to get drawn into listing the mass of technologies involved, and therefore easy to get confused about what you need to know. SOAP, WSDL, UDDI, and DISCO all play valid parts in the process of making a web service available. However, you don’t need to know about any of these acronyms to be able to use a web service.

428