In Part I we developed a set of classes that are essential for
our help desk application. Now it s time to start developing the Web site. To
begin, we ll configure our Web site to use forms authentication. We ll
configure authentication, membership, roles, and e-mail service via
configuration files. All the user interface attributes such as fonts and colors
are stored in a theme. Further, we ll need a couple of master pages applied to
various Web forms. Finally, we ll need user registration and log-in capabilities.
We ll make use of such ASP.NET AJAX server controls as UpdatePanel,
UpdateProgress, and Timer, which make Web applications more responsive, rich,
and user friendly.

Configuring the Connection String

To begin, add a database connection string in the
section. This connection string points to the HelpDeskDb database we created in
Part I. Open the web.config file in Visual Studio and
modify its section as shown here:

connectionString="data
source=.;

initial
catalog=HelpDeskDb;user id=sa;password=pwd"

providerName="System.Data.SqlClient"/>

The name of the connection string is connectionstring; it
points to the HelpDeskDb database. Make sure to change the connection string to
suit your environment. This connection string is used by the
and sections later.

Configuring Security

The help desk application consists of different areas for
customers and support personnel. This requires some authentication scheme to
validate the users. We ll use Forms authentication in our application and the
section to configure it:

The mode attribute of the section
specifies the authentication mode as Forms. The tag inside the
section configures the login page to be Login.aspx using the loginUrl
attribute. This is how ASP.NET knows where to redirect users for logging in if
they are not yet authenticated. Simply adding the
section is not enough. You also need to ban all the anonymous users from
accessing the site with the help of the section. The
tag inside the section sets the users attribute to ?,
indicating that access to all the users whose identity is in question is to be
denied.

Configuring Membership and Role Providers

The section simply enables Forms-based
authentication. We use Membership features of ASP.NET 2.0 for user validation. To
use Membership features the underlying database must be configured using the
aspnet_regsql.exe tool. To save some space we won t discuss this tool here, but
make sure to run this tool on the HelpDeskDb database so as to create the required
tables and stored procedures. Once the database is configured for Membership
features add to the web.config file the markup shown here:

connectionStringName="connectionstring"

type="System.Web.Security.SqlMembershipProvider"/>

The section adds a membership provider
named MyProvider. The connectionStringName attribute points to the connection
string we defined earlier. Finally, the type attribute specifies the type that
is acting as the membership provider (SqlMembershipProvider in our example).

The help desk application needs to implement role-based
security because some pages are accessible to customers and some are not. We
need two roles: Customer and SupportPerson. Before we create these roles in the
system it is important to configure a role provider. To do so, add a
section to the web.config file:

connectionStringName="connectionstring"

type="System.Web.Security.SqlRoleProvider"/>

The tag enables role features by
setting its enabled attribute to true. It then adds a role provider named
MyProvider. The connectionStringName attribute is the same as before, but
notice the type attribute this time it is SqlRoleProvider.

Configuring E-mail Service

After support personnel responds to an issue, the help desk
application sends an e-mail notification to the customer. This calls for
configuring SMTP service in the web.config file. The
section takes care of this configuration:

host="localhost"/>

Notice that the section comes under the
configuration section. Furthermore, notice that the
section is outside the section. The from attribute of the section
specifies the sender s e-mail address. This way you need not specify a sender s
e-mail address while sending e-mails from your code. Make sure to change this
address as per your requirements. The tag configures the SMTP
host as localhost. Instead of localhost, you can specify your own SMTP server.
The defaultCredentials attribute indicates whether to use Windows user
credentials for authentication purposes. If you wish to use specific user
credentials for authentication purposes, use the UserName and Password
attributes of the tag.

One way to apply a theme to Web forms is to specify it in
the theme attribute of the @Page directive. However, that requires setting the theme
attribute of every Web form. An easier approach is to specify the theme in the configuration
file; the tag of the web.config file allows us to do just that:

...

As you can see, the theme attribute of the
tag specifies the name of the theme. This completes the theme of our help desk
application.

Master Pages

Now we ll develop two master pages. We need one master
page for all the Web forms used by customers and another for all the Web forms
used by support personnel. Before you add master pages, add two folders named
Customer and Support under the root folder of the Web site. The Customer folder
will contain a master page and Web forms related to customers; the Support
folder will contain a master page and Web forms related to support personnel.

Now add inside the Customer folder a new master page named
CustomerMasterPage.master. Drag and drop a Label control at the top of the
master page and set its Text property to Help Desk. Drag and drop a
ScriptManager control below the Label. The help desk application uses ASP.NET
AJAX server controls like UpdatePanel and UpdateProgress. These controls
require that the ScriptManager control be present on the page. Next, drag and
drop a Label control below the ScriptManager control and set its Text property
to Welcome. Also, drag and drop a LoginName and a LoginStatus control beside
the Welcome label. The LoginName control will display the name of the logged-in
user and the LoginStatus control will allow users to log out. Add a horizontal
rule (

) below the Welcome label. Now drag and drop two HyperLink
controls and set their properties as shown in Figure 5.

ID

Property

Value

HyperLink1

Text

New Issue

NavigateUrl

~/customer/postissue.aspx

SkinId

MenuLink

HyperLink2

Text

History

NavigateUrl

~/customer/history.aspx

SkinId

MenuLink

Figure 5: Setting the
properties of HyperLink controls in CustomerMasterPage.master.

Now add another master page named
SupportMasterPage.master. This master page is similar to the one we just
developed, except that it consists of three HyperLink controls. The HyperLink
controls and their properties are described in Figure 8. This completes
development of both master pages.

ID

Property

Value

HyperLink1

Text

Pending Issues

NavigateUrl

~/support/pendingissues.aspx

SkinId

MenuLink

HyperLink2

Text

Selected Issues

NavigateUrl

~/support/selectedissues.aspx

SkinId

MenuLink

HyperLink3

Text

All Issues

NavigateUrl

~/support/history.aspx

SkinId

MenuLink

Figure 8: Setting the
properties of HyperLink controls in SupportMasterPage.master.

User Registration and Log-in

The help desk application needs a user registration facility
wherein customers can register themselves. Further, they should be able to log
in to the Web site and access their area. We ll create a login page, Login.aspx,
that will allow users to register and log in to the Web site. Begin by adding a
new Web form named Login.aspx. Drag and drop a ScriptManager control on the Web
form (the UpdatePanel and UpdateProgress controls require a ScriptManager
control on the page). Then drag and drop an UpdatePanel control on the Web
form. Place a Login control inside the UpdatePanel. The UpdatePanel control
allows partial page rendering instead of posting back the whole page. Now drag
and drop an UpdateProgress control below the UpdatePanel and set its
AssociateUpdatePanelID property to UpdatePanel1. The UpdateProgress control is
used to display a progress indicator when the UpdatePanel is being refreshed.
Place a Label control inside the UpdateProgress control and set its Text
property to Please wait...signing in...; set the SkinId property of the Label
to Message.

Next, drag and drop another UpdatePanel control on the
form and place a CreateUserWizard control inside it. Also, drag and drop
another UpdateProgress control below the second UpdatePanel and set its
AssociateUpdatePanelID property to UpdatePanel2. Add a Label control to the
second UpdateProgress and set its Text and SkinId properties to Please
wait...registration in progress... and Message, respectively. The Login.aspx
should now resemble Figure 9.

Figure 9:
Login.aspx in design mode.

The help desk application has two application-specific
roles: Customer and SupportPerson. New users who register with the system are by
default assigned a Customer role. This is done by handling the CreatedUser
event of the CreateUserWizard control:

protected void CreateUserWizard1_CreatedUser(object sender,

EventArgs e)

{

Roles.AddUserToRole(CreateUserWizard1.UserName,
"Customer");

}

The CreatedUser event of the CreateUserWizard control is
raised when a new user successfully registers with the Web site. Inside we call
the AddUserToRole method of the Roles object. The AddUserToRole method takes
two parameters: the name of the user and the name of the role to which the user
is to be added. In our example the UserName property of the CreateUserWizard
control returns the name of the newly registered user.

Once a user logs in to the system they should be taken to the
appropriate area depending on their role. This is achieved by handling the LoggedIn
event of the Login control. The LoggedIn event is raised when a user
successfully logs in to the application:

protected void Login1_LoggedIn(object sender, EventArgs e)

{

if (Roles.IsUserInRole(Login1.UserName,"Customer"))

{

Response.Redirect("~/customer/postissue.aspx");

}

if
(Roles.IsUserInRole(Login1.UserName,"SupportPerson"))

{

Response.Redirect("~/support/pendingissues.aspx");

}

}

Inside the LoggedIn event handler we use the IsUserInRole
method of the Roles object to determine whether the user is part of the Customer
role. If so, we redirect the user to the PostIssue.aspx page. Similarly, if the
user is part of the SupportPerson role, we redirect the user to
PendingIssues.aspx.

Before you run Login.aspx and test user registration and
log-in functionality, you must create two roles in the system: Customer and
SupportPerson. To create these roles we use the Web Site Administration Tool,
which can be invoked via the Website | ASP.NET Configuration menu option (see Figure
10).

Figure 10:
Creating roles using the Web Site Administration Tool.

Once we create the required roles we can run Login.aspx
and register new users. Figure 11 shows a sample user registration.

Figure 11:
Creating new users.

Notice how the UpdateProgress control displays a progress
indicator message after we click the Create User button. Also notice there is
no postback after we click the Create User button. This is because the
CreateUserWizard control is placed inside an UpdatePanel control; only that
UpdatePanel control gets refreshed after we click the Create User button.

Create at least four users for testing purposes (Customer1,
Customer2, Support1, and Support2). By default, all the users are added to the Customer
role. Add the users Support1 and Support2 to the SupportPerson role using the Web
Site Administration Tool (see Figure 12). Note: You won t be able to test log-in
functionality immediately because we haven t yet developed the Web forms for
customers or support personnel.

Figure 12:
Adding users to the SupportPerson role.

Posting an Issue

Now create a Web form that allows customers to post an issue
or request. Begin by adding a new Web form named PostIssue.aspx in the Customer
folder. Make sure to check the Select master page checkbox in the Add New Item
dialog box (see Figure 13).

Figure 13:
Adding a new Web form.

Visual Studio will prompt you to select a master page for
the new Web form (see Figure 14); select CustomerMasterPage.master from the Customer
folder.

Figure 14:
Selecting a master page.

Drag and drop an UpdatePanel control on the Web form. Add
a Panel control inside the UpdatePanel control. Then add a table inside the
Panel control and design the table as shown in Figure 15.

Figure 15:
Designing PostIssue.aspx.

The table consists of textboxes for entering the subject
and description of an issue (both are validated using RequireFieldValidator
controls). The SkinId property of the Post an Issue label is set to Heading.
Similarly, the SkinId property of Label5 is set to Message. Now drag and drop
an UpdateProgress control below the UpdatePanel control and set its
AssociatedUpdatePanelID property to UpdatePanel1. Add a Label inside the
UpdateProgress control and set its Text property to Please wait...; set the SkinId
property of the Label to Message. In the Click event handler of the Submit
button write code to insert an issue in the Issues table:

protected void Button1_Click(object sender, EventArgs e)

{

MembershipUser user=Membership.GetUser();

Issues.Add(TextBox1.Text, TextBox2.Text, user.UserName);

Panel1.Visible = false;

Label5.Text = "Your issue has been posted. Our support will

contact you shortly. Thank
you!";

}

This code retrieves the current user by calling the GetUser
method of the Membership object. It then calls the Add method of the Issues
class. The Add method accepts a subject and description of an issue and name of
the user who is posting the issue. After adding the issue the Visible property
of the Panel is set to false and a success message is displayed in a Label
control. Figure 16 shows PostIssue.aspx in action. Notice that the controls (such
as HyperLink and Label) assume the formatting as specified in the skin file of the
MyTheme theme.

Figure 16:
Sample run of PostIssue.aspx.

Viewing a History of Issues

Customers should be able to see a history of all the
issues posted by them. Hence, we ll develop another Web form named History.aspx
inside the Customer folder. Make sure to select CustomerMasterPage.master as
its master page. Then drag and drop a Label control on it and set its Text
property to Issue History. Also, set its SkinId property to Heading. Now drag and
drop an Object Data Source control on the Web form. Open the smart tag of the
Object Data Source control and choose Configure Data Source... (see Figure 17).
Doing so will start a wizard. The first step of the wizard allows us to choose
a business object (see Figure 18). Select Issues as the business object and
click the Next button. On the second step choose the select method
SelectByCustomerId (see Figure 19).

Figure 17:
Smart tag of the Object Data Source control.

Figure 18:
Choosing a business object.

Figure 19:
Choosing a select method.

We simply need to show the issue history, so we need not
set update, insert, and delete methods of the Object Data Source control.
Clicking Next displays the last step of the wizard, wherein we are asked to supply
a value or source for the postedby parameter of the SelectByCustomerId method.
We ll supply this parameter via code, so select None from the Parameter Source
combobox and finish the wizard (see Figure 20).

Figure 20:
Specifying parameters for the select method.

Now drag and drop an UpdatePanel control below the Object
Data Source control. Add a GridView control inside it. Open the smart tag for
the GridView and choose Data Source as ObjectDataSource1. Also enable paging
for the GridView (see Figure 21).

Figure 21: The
smart tag of GridView.

Click on the Edit Columns option from the smart tag of
GridView to open the Fields dialog box, as shown in Figure 22.

Figure 22:
Adding columns to the issue history GridView.

Add one HyperLinkField and two BoundFields to the
GridView. Set the properties of these three columns as shown in Figure 23.

Column

Property

Value

HyperLinkField

HeaderText

Issues

DataNavigateUrlFields

IssueId

DataNavigateUrlFormatString

~/displaythread.aspx?issueid={0}

DataTextField

Title

BoundField

HeaderText

Posted On

DataField

PostedOn

DataFormatString

{0:d}

BoundField

HeaderText

Resolved On

DataField

ResolvedOn

DataFormatString

{0:d}

Figure 23: Setting
properties of GridView columns.

Observe the properties of HyperLinkField carefully. This
column renders hyperlinks pointing to DisplayThread.aspx. We must pass an issue
ID to DisplayThread.aspx as a querystring parameter. This is done with the help
of the DataNavigateUrlFormatString property. Notice the use of the {0} place
holder to represent the issue ID. The actual value of the issue ID is
substituted at run time depending on the DataNavigateUrlFields property.

We must supply the postedby parameter of the SelectByCustomerId
method in the Page_Load event of the Web form; here s the Page_Load event
handler of History.aspx:

protected void Page_Load(object sender, EventArgs e)

{

MembershipUser user=Membership.GetUser();

ObjectDataSource1.SelectParameters["postedby"]

.DefaultValue = user.UserName;

}

This code retrieves the current user using the GetUser
method of the Membership object. It then sets the DefaultValue property of the postedby
parameter from the SelectParameters collection of the Object Data Source
control. This way the history of the currently logged in customer alone is
shown. Run History.aspx and you should see something similar to Figure 24. This
completes development of customer-specific Web forms.

Figure 24:
Sample run of History.aspx.

Conclusion

In this second part of the series we configured the help desk
application for membership and roles. We also developed a theme that
encapsulates the look and feel of various server controls. We developed two
master pages, one for customer-related pages and one for support personnel-related
pages. The help desk application uses forms authentication, so we developed a
user registration and log-in page. Controls such as Login and CreateUserWizard
save us a lot of work. We used ASP.NET AJAX controls such as UpdatePanel and
UpdateProgress. The UpdatePanel control helps provide an improved user
experience by allowing partial page rendering, and it significantly reduces
postbacks, improving overall performance. Finally, we developed two Web forms
for posting an issue and viewing the history of issues. In Part III of this
series we ll develop Web forms specific to support personnel.

Bipin Joshi is the
founder and owner of BinaryIntellect Consulting (http://www.binaryintellect.com),
where he conducts professional training programs on .NET technologies. He is
the author of Developer s Guide to ASP.NET 2.0
(http://www.binaryintellect.com/books)
and co-author of three Wrox books on .NET 1.x. He writes regularly for http://www.DotNetBips.com, a community
Web site he founded in the early days of .NET. He is a Microsoft MVP, MCAD,
MCT, and member of ASPInsiders. He jots down his thoughts about .NET, life, and
Yoga at http://www.bipinjoshi.com. He
also conducts workshops on Yoga and Meditation, where he helps IT professionals
develop a positive personality. You can contact him at mailto:[email protected].