In ASP.NET you can easily create custom fields to store additional user information rather than username, email, password etc. Let’s get started, in one of my recent ASP.NET application I wanted to store user’s full name, district and other information when they register through the application. So how can I go about this?
First of all lets declare these variables in the web.config file so that it can be accessible globally from any page. I have added the following lines in the web.config file.
<profile enabled="true"> <properties> <add name="District" type="string"/> <add name="FullName" type="string"/> <add name="Telephone" type="string"/> <add name="Title" type="string"/> <add name="Campground" type="string"/> <add name="Campfire" type="string"/> <add name="lastlogin" type="datetime"/> <add name="notification" type="String"/> </properties> <providers> <clear/> <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/"/> </providers> </profile>
Make sure this block is inside the <system.web> tag.
Once I have these fields setup in the web.config file I will be able to access them from any page in my application. Now I need to implement these additional fields in the registration page so that I can capture additional information. Here is the code for my create user page.
<div id="msg" runat="server" ></div> <span class="failureNotification"> <asp:Literal ID="ErrorMessage" runat="server"></asp:Literal> </span> <asp:ValidationSummary ID="RegisterUserValidationSummary" runat="server" CssClass="vSummary" ValidationGroup="RegisterUserValidationGroup"/> <div > <table width="100%" > <tr><th>User Name:</th><td><asp:TextBox ID="txtUserName" runat="server" CssClass="textEntry"></asp:TextBox> <asp:RequiredFieldValidator ID="UserNameRequired" runat="server" ControlToValidate="txtUserName" CssClass="failureNotification" ErrorMessage="User Name is required." ToolTip="User Name is required." ValidationGroup="RegisterUserValidationGroup">*</asp:RequiredFieldValidator><asp:Button ID="btnCheckUser" runat="server" Text="Check User" /></td></tr> <tr><th> Full Name:</th><td> <asp:TextBox ID="txtFullName" runat="server" CssClass="textEntry" ReadOnly="true"></asp:TextBox><asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ControlToValidate="txtFullName" CssClass="failureNotification" ErrorMessage="User Name is required." ToolTip="Full Name is required." ValidationGroup="RegisterUserValidationGroup">*</asp:RequiredFieldValidator></td></tr> <tr><th>E-mail: </th><td> <asp:TextBox ID="txtEmail" runat="server" CssClass="textEntry" AutoCompleteType="Email" ReadOnly="true"></asp:TextBox><asp:RequiredFieldValidator ID="EmailRequired" runat="server" ControlToValidate="txtEmail" CssClass="failureNotification" ErrorMessage="E-mail is required." ToolTip="E-mail is required." ValidationGroup="RegisterUserValidationGroup">*</asp:RequiredFieldValidator></td></tr> <tr><th>Job Title: </th><td> <asp:TextBox ID="txtTitle" runat="server" CssClass="textEntry" ReadOnly="true"></asp:TextBox></td></tr> <tr><th> District:</th><td> <asp:CheckBoxList ID="chkDistrict" DataSourceID="dsDistricts" DataTextField="district" DataValueField="district" runat="server" RepeatColumns="5"> </asp:CheckBoxList> <asp:SqlDataSource ID="dsDistricts" runat="server" SelectCommand="select distinct district from camp_sites order by district asc" ConnectionString="<%$ ConnectionStrings:ApplicationServices %>"> </asp:SqlDataSource> </td></tr> <tr> <th> User Role: </th> <td> <asp:CheckBoxList ID="chkRoles" runat="server" RepeatColumns="6"> </asp:CheckBoxList> </td> </tr> <tr><th> <asp:Button ID="btnCancel" runat="server" Text="Done" CssClass="cancel" CausesValidation="false" PostBackUrl="~/ManageUsers.aspx" /></th><td><asp:Button ID="CreateUserButton" runat="server" Text="Create User" ValidationGroup="RegisterUserValidationGroup" CssClass="button" /> </td></tr> <tr><th> </th><td> </td></tr> </table>
Please note I have used couple of checkbox list to assign multiple districts and user roles in this registration page. I will not go through binding data in the checkbox list in this post. This tutorial is to basically show you how to save data in user profile. The registration screen looks like this –
The above example includes also looking up the user information from Active Directory (AD) and I have implemented custom LDAP authentication. So I am not entering password in this screen since it will validate the user authentication from AD.
In the register.aspx.vb page I have following code for register button click event.
Protected Sub CreateUserButton_Click(sender As Object, e As System.EventArgs) Handles CreateUserButton.Click Dim username As String = txtUserName.Text.ToString 'Dim password As String = txtPassword.Text.ToString Dim email As String = txtEmail.Text.ToString Dim strRoles As String = "" Try ' Create new user. Dim newUser As MembershipUser = Membership.CreateUser(username, "password", email) ' If user created successfully, set password question and answer (if applicable) and ' redirect to login page. Otherwise Return an error message. Dim userProfile As ProfileCommon = ProfileCommon.Create(username, True) 'get the user information from the wizard 'userProfile.District = dlDistricts.SelectedValue 'collect and format the checkbox list values and set to string variable Dim st As String = commonTasks.GetStringFromCheckBoxList(chkDistrict) userProfile.District = st userProfile.FullName = txtFullName.Text userProfile.Title = txtTitle.Text 'save data into profile userProfile.Save() 'Roles.AddUserToRole(newUser.UserName, "admin") 'add user to roles For Each lst As ListItem In chkRoles.Items If lst.Selected Then ' Add the user to the role Roles.AddUserToRole(newUser.UserName, lst.Value) End If Next msg.InnerHtml = " <div class='ui-widget'> <div class='ui-state-default ui-corner-all' style='padding: 0 .7em; font-size:12px'><p><span class='ui-icon ui-icon-alert' style='float: left; margin-right: .3em;'></span>" & "User has been created!</p></div></div>" Dim msgBody As String = "<p>Dear " & txtFullName.Text msgBody += "<br /> You have been granted access to the Campground Systems. Please find your login information below to access the backend system.</p>" msgBody += "<div style='padding: 15px; background-color: #BFCBD6; left: 13px;'>Username: <b> " & txtUserName.Text ' msgBody += "</b><br /> Password: " & txtPassword.Text msgBody += "<br /> District: " & st msgBody += "</div><p>Test Frontend: http://xx.wa.gov.au/campground-status </p>" msgBody += "<p>Backend: https://xxx.au/campgrounds/ </p>" msgBody += "<p>Please contact Mohammed Tajuddin at mohammed.tajuddin@xxx.xx.gov.au if you have any issue accessing the system.</p>" msgBody += "<br /><br /> Kind regards,<br />System Admin<br />" msgBody += "<p style='color:red;'><i>Note: Please note this is an automated email and don't reply to this email.</i></p>" 'send email MailHelper.SendMailMessage("ratis@xx.gov.au", txtEmail.Text, "", "", "mohammed.tajuddin@xx.gov.au", "Campgrounds System Access", msgBody) txtFullName.Text = "" txtEmail.Text = "" 'txtPassword.Text = "" txtUserName.Text = "" 'Display a client-side popup, explaining that the email has been sent ClientScript.RegisterStartupScript(Me.GetType(), "Alert!", String.Format("alert('An email with authentication details has been send to {0}');", email.ToString), True) 'ToAddress.Replace("'", "\'") Catch ex As MembershipCreateUserException msg.InnerHtml = GetErrorMessage(ex.StatusCode) Catch ex As HttpException msg.InnerHtml = ex.Message End Try
Now lets explain the above code, first create user based on entered username and password. Once user is created, create a common profile and set the values for the profile fields from the text fields.
Remember to save the profile values once set.
That’s it now it should save the profile value and you can use them as you like.
Please note in the above code I have also implemented email notification to user when they are registered. This email also send their password and application URLs etc.
Update profile value for all users
Sometimes you might need to update the default profile value for all users. To update all users at one go, you can use the following code.
'update all users profile Dim users = Membership.GetAllUsers() Dim userList = New List(Of MembershipUser)() For Each user As MembershipUser In users pc = Profile.GetProfile(User.ToString) pc.lastlogin = Date.Now.AddYears(-20) pc.Save() Next
In the above example I have loaded all the users then set the lastLogin value to 20 years before today.
Happy programming!