Consuming Membership and Profile Services via ASP.NET AJAX
ASP.NET 2.0 introduced various application services—such as Membership, Roles, and Profiles—that eliminate a lot of coding that was required to provide the same functionality. However, these services are part of ASP.NET's server-side framework, which could pose a challenge when you use ASP.NET AJAX to consume the services from client-side JavaScript code. Fortunately, ASP.NET AJAX provides an out-of-the-box solution to this problem. This article explains how to use this solution in C# with Visual Studio.
Sample Scenario
User Registration
First of all, you will create the user registration page. Add a new web form named Registration.aspx. Drag and drop a ScriptManager control from the toolbox (see Figure 2).
Figure 2. Drag and Drop a ScriptManager Control
Add a table into the UpdatePanel and design it as shown in Figure 3.
Figure 3. Design for Table in the UpdatePanel
[WebMethod]
public static bool CheckAvailability(string uid)
{MembershipUser user = Membership.GetUser(uid);
if (user == null)
{return true;
}
else {return false;
}
}
protected void Button1_Click(object sender, EventArgs e)
{ try {MembershipUser user = Membership.CreateUser
(TextBox2.Text, TextBox3.Text, TextBox5.Text);
ProfileCommon pc = Profile.GetProfile(user.UserName);
pc.FullName = TextBox1.Text;
pc.DOB = DateTime.Parse(TextBox6.Text);
pc.Address.Street = TextBox7.Text;
pc.Address.Country = TextBox8.Text;
pc.Address.PostalCode = TextBox9.Text;
pc.Save();
lblMsg.Text = "User created successfully!";}
catch (Exception ex) {lblMsg.Text = ex.Message;
}
}
function CheckAvailability()
{var uid=document.getElementById('TextBox2').value;
if(uid=="")
{ alert('Please enter user ID!');return false;
}
PageMethods.CheckAvailability(uid,OnComplete);
return false;
}
function OnComplete(result)
{ var lblMsg=document.getElementById('lblMsg'); if(result) { lblMsg.innerText="The ID is available!";}
else { lblMsg.innerText="The ID is unavailable!";}
}
Figure 4. Sample Run of the Web Form
Developing a Login Page
Now that users can register themselves with the web site, you need to provide a facility that enables them to log in and access various pages. To do so, add a new web form called Login.aspx to the web site. Remember that you have set the loginUrl attribute of the forms tag to Login.aspx. Drag and drop a ScriptManager control on it and design the login page as shown in Figure 5 by assembling various controls.
Figure 5. The Login Page Design
As you can see, the login page consists of textboxes for entering a user ID and password. The "Remember Me" checkbox allows you to preserve your logged-in status even after closing the browser window. The TextMode property of the password textbox is set to Password. Further, the OnClientClick property of the Login button is set to "return BeginAuthenticateUser();". BeginAuthenticateUser() is a JavaScript function that uses the ASP.NET AJAX authentication service to authenticate the user. The following is the BeginAuthenticateUser() function:
function BeginAuthenticateUser()
{var uid;
var pwd;
var isPersistent;
uid=document.getElementById('TextBox1').value;
pwd=document.getElementById('TextBox2').value;
isPersistent=document.getElementById('CheckBox1').checked;
Sys.Services.AuthenticationService.login
(uid,pwd,isPersistent,null,null,
EndAuthenticateUser,OnError,uid);
return false;
}
The BeginAuthenticateUser() JavaScript function retrieves the user IDs and passwords entered in their respective textboxes. It also retrieves the status of the "Remember Me" checkbox. ASP.NET AJAX provides a built-n class called AuthenticationService that resides in the Sys.Services namespace. Remember that the Sys.Services namespace is defined by the client-side framework of ASP.NET AJAX. The AuthenticationService class offers two methods: login() and logout(). The code above used the login() method, which takes in all eight parameters. Their significance is listed below:
Parameter Significance
- A user ID
- A password
- A boolean value indicating whether an authentication cookie will be persistent
- The web page where the user should be redirect after a successful login
- Reserved for future use
- A callback function that will be called after a successful login (EndAuthenticateUser in this example)
- A callback function that will be called in case a login attempt fails (OnError in this example)
- A custom value that is passed to the callback functions
If the user is successfully authenticated, the EndAuthenticateUser function will be called. The following is the EndAuthenticateUser function:
function EndAuthenticateUser(result,userContext,methodName)
{ if(result) { window.location='default.aspx';}
else { alert("Unable to login! Please check user id and password!!");}
}
The EndAuthenticateUser() function takes three parameters: the result of the login operation, the user context that you passed earlier in the eighth parameter of the login() method, and the method name. Inside, it checks whether the result is true (in other words, the user is successfully authenticated) and, if so, it sets the location property of the windows object to default.aspx. This way, the user is redirected to the default page after a successful login attempt. If there is any error, an error message is displayed using the alert() function.
The OnError() function is called whenever an error occurs when calling the authentication service. This function is shown below:
function OnError(result,userContext,methodName)
{
alert(result.get_message());
}
The function simply displays an error message to the user. The result parameter received is actually an object and has a method called get_message() that returns a descriptive error message.
This completes the login page.
Implementing Logout Functionality
Add another web form called Default.aspx. This web form will allow users to logout and manage their profiles. Firstly, you will implement logout functionality. Drag and drop a ScriptManager control on the Default.aspx and design the web form as shown in Figure 6.
protected void Page_Load(object sender, EventArgs e)
{
Label4.Text = Membership.GetUser().UserName;
}
function BeginLogOut()
{Sys.Services.AuthenticationService.logout
(null,EndLogout,OnError,null);
return false;
}
function EndLogout(result)
{ //nothing here}
- The first parameter indicates a URL where the user should be taken after successful logout.
- The second parameter specifies a callback function to be called when the logout operation is complete.
- The third parameter specifies a callback function to be called when the logout operation fails.
- The fourth parameter indicates a custom context information.
Reading Profile Properties
function pageLoad()
{
var panel3=document.getElementById('Panel3');
panel3.style.visibility="hidden";
}
function BeginProfileLoad()
{if(event.srcElement.value=="Show my profile")
{ var panel3=document.getElementById('Panel3'); panel3.style.visibility="visible";event.srcElement.value="Hide my profile";
Sys.Services.ProfileService.load
(null,EndProfileLoad,OnProfileFailed, null);
}
else { var panel3=document.getElementById('Panel3'); panel3.style.visibility="hidden";event.srcElement.value="Show my profile";
}
return false;
}
Parameter
Significance
- An array of property names that are to be loaded. If you have too many profile properties, then it makes sense to load the ones that you really want to use. This will improve the performance of your page.
- A callback function that will be called when the load operation is completed
- A callback function that will be called if the load operation fails
- Custom context information, if any
Once the profile is loaded the EndProfileLoad() function is called. This is the EndProfileLoad():
function EndProfileLoad(numProperties, userContext, methodName)
{document.getElementById('TextBox3').value =
Sys.Services.ProfileService.properties.FullName;
document.getElementById('TextBox4').value =
Sys.Services.ProfileService.properties.DOB;
document.getElementById('TextBox5').value =
Sys.Services.ProfileService.properties.Address.Street;
document.getElementById('TextBox6').value =
Sys.Services.ProfileService.properties.Address.Country;
document.getElementById('TextBox7').value =
Sys.Services.ProfileService.properties.Address.PostalCode;
}
Modifying Profile Properties
function BeginSaveProfile()
{Sys.Services.ProfileService.properties.FullName=
document.getElementById('TextBox3').value;
Sys.Services.ProfileService.properties.DOB=
document.getElementById('TextBox4').value;
Sys.Services.ProfileService.properties.Address.Street=
document.getElementById('TextBox5').value;
Sys.Services.ProfileService.properties.Address.Country=
document.getElementById('TextBox6').value;
Sys.Services.ProfileService.properties.Address.PostalCode=
document.getElementById('TextBox7').value;
Sys.Services.ProfileService.save
(null,EndSaveProfile,OnProfileFailed,null);
return false;
}
function EndSaveProfile(numProperties, userContext, methodName)
{
alert('Your profile is saved successfully!');
}
Figure 7. A Sample Run of the Default.aspx