How to add a Login, Roles and Profile system to an ASP.NET 2.0 app in only 24 lines of code

 

I’ve seen a few questions in the forums lately looking for examples on how to use the CreateUserWizard control to create new users in the ASP.NET 2.0 membership system, and then as part of the registration process assign the new user into custom roles and/or collect and store custom profile properties about them (country, address, gender, zipcode, etc).

Stefan from my team had a cool CreateUserWizard control sample that I borrowed and expanded upon to build-up a sample that demonstrates how to build a fairly common user management, roles and personalization system in ASP.NET 2.0 that does this. I was pleasantly surprised to find it only took about 25 lines of C# code in the entire app. J

The sample comes with 6 pages:

Specifically it supports:

1) Login support to enable registered users to login to the web app using forms auth and the new membership system (login.aspx)

2) Registration support to enable visitors to create and register new users in the membership system (CreateNewWizard.aspx)

3) Profile support that enables the site to gather information about the user on registration, and for the users to see that information on a profile page (MyProfile.aspx).

4) Change Password support to enable registered users to change their password in the membership system (ChangePassword.aspx)

5) Password Recovery support to enable users to reset their password if they forgot them (RecoverPassword.aspx)

You can download and run the sample yourself from here. Note that it is built with the final release of VS 2005 and ASP.NET 2.0 – so it won’t work with Beta2 (although it will probably work with the RC).

Implementation Notes on CreateNewWizard.aspx and MyProfile.aspx:

Only two of the above pages (CreateNewWizard.aspx and MyProfile.aspx) have code in them. The others use the built-in Login controls in V2 to-do everything (asp:login, asp:passwordrecovery, asp:changepassword).

CreateNewWizard.aspx is the most interesting page. It uses the built-in <asp:createuserwizard> server control to-do most of the heavy lifting and has two templated wizard steps defined within the wizard:

<asp:createuserwizard> wizard step 1: gathering user-account data

The <asp:createuserwizard> control handles gathering up the user-account, email, password, and password recovery/answer data and then calling into the ASP.NET 2.0 membership system to register the new user. You simply have to override the control’s <createuserwizardstep> template and customize the control layout to have things look how you want.

The sample is using the ASP.NET validation controls to perform client-side validation on the inputs as well within the template (example: making sure passwords match, the age is a valid integer, etc). One added benefit in ASP.NET 2.0 is that these validation controls now support client-side validation for FireFox and other modern browsers (note: all screenshots were done using FireFox).

There are then three additional properties (their country, gender and age) that I wanted to gather up about the new user as part of the registration process. Doing this was pretty easy using the new ASP.NET 2.0 Profile system – simply add their definitions within the <profile> tag of the web.config file to register them and store their values in the new profile system:

<profile enabled="true">

<properties>

<add name="Country" type="string"/>

<add name="Gender" type="string"/>

<add name="Age" type="Int32"/>

</properties>

</profile>

I then handled the “CreatedUser” event on the CreateUserWizard control within my CreateNewWizard.aspx.cs code-behind file to retrieve the values from the controls within the CreateUserWizard control template and set them in the profile store:

// CreatedUser event is called when a new user is successfully created

public void CreateUserWizard1_CreatedUser(object sender, EventArgs e) {

// Create an empty Profile for the newly created user

ProfileCommon p = (ProfileCommon) ProfileCommon.Create(CreateUserWizard1.UserName, true);

// Populate some Profile properties off of the create user wizard

p.Country = ((DropDownList)CreateUserWizard1.CreateUserStep.ContentTemplateContainer.FindControl("Country")).SelectedValue;

p.Gender = ((DropDownList)CreateUserWizard1.CreateUserStep.ContentTemplateContainer.FindControl("Gender")).SelectedValue;

p.Age = Int32.Parse(((TextBox)CreateUserWizard1.CreateUserStep.ContentTemplateContainer.FindControl("Age")).Text);

// Save profile - must be done since we explicitly created it

p.Save();

}

Because the user is being created as part of this step, I explicitly choose to create a new Profile object in code (note that I was passing in the CreatedUserWizard1.UserName property as the username – since the user isn’t logged into the system yet). I then accessed the controls within the template of the <asp:createuserwizard> control, pulled out their values, and stuck them within the newly created profile. Calling p.save at the end registered this profile with the new username. (note: I’ll walk through how we use this profile data later in a page below).

<asp:createuserwizard> wizard step 2: picking roles

After the user fills out the first step of registration information and clicks the next button, the user is created, the CreatedUser event fires, and we fill in the appropriate information about the user into the profile store.

The <asp:createuserwizard> control then displays the second step template we’ve defined. This template lists all of the roles currently created in the ASP.NET Role Management system, and allows the user to select which roles they belong to:

Note that you’d typically never assign roles to an end-user this way (instead you’d add your own logic to somehow calculate which role they belong in), but I thought this scenario was cool nonetheless which is why it works like the sample above.

I think it is cool because of the way we populate and access these roles in the template of the <asp:createuserwizard>. Basically, we have a template definition to the .aspx like this:

<asp:WizardStep runat="server" AllowReturn="False"

OnActivate="AssignUserToRoles_Activate"

OnDeactivate="AssignUserToRoles_Deactivate">

<table>

<tr>

<td>

Select one or more roles for the user:

</td>

</tr>

<tr>

<td>

<asp:ListBox ID="AvailableRoles" runat="server"

SelectionMode="Multiple" >

</asp:ListBox>

</td>

</tr>

</table>

</asp:WizardStep>

It simply contains a <asp:listbox> control named “AvailableRoles”. When this wizard step is loaded (after the user hits the next button on the first step in the wizard), it will fire the “OnActivate” event. We can use this to databind the list of all roles in the system to the above listbox. When the user hits next again, the wizard will fire the “OnDeactivate” event. We can then use this to determine which roles were selected in the above listbox, and use them to update the role-manager system.

The code to-do both of these actions looks like this:

// Activate event fires when user hits "next" in the CreateUserWizard

public void AssignUserToRoles_Activate(object sender, EventArgs e) {

// Databind list of roles in the role manager system to listbox

AvailableRoles.DataSource = Roles.GetAllRoles(); ;

AvailableRoles.DataBind();

}

// Deactivate event fires when user hits "next" in the CreateUserWizard

public void AssignUserToRoles_Deactivate(object sender, EventArgs e) {

// Add user to all selected roles from the roles listbox

for (int i = 0; i < AvailableRoles.Items.Count; i++) {

if (AvailableRoles.Items[i].Selected == true)

Roles.AddUserToRole(CreateUserWizard1.UserName, AvailableRoles.Items[i].Value);

}

}

That is all of the code for the CreateNewWizard.aspx.cs file – 17 lines total if you omit comments and whitespace (if my count is right).

Next Step: Displaying User Profile Data

The only other page in this scenario that required me to add code was the MyProfile.aspx page. This page looks like this:

The page itself was pretty simple to implement. I simply added a few asp:label controls on the page, as well a listbox for the roles. Populating these controls with the profile and role information involved added a Page_Load event with 7 lines of code like so:

protected void Page_Load(object sender, EventArgs e) {

Country.Text = Profile.Country;

Gender.Text = Profile.Gender;

Age.Text = Profile.Age.ToString();

RoleList.DataSource = Roles.GetRolesForUser(User.Identity.Name);

RoleList.DataBind();

}

Note that the profile object is strongly typed – which means profile properties will get statement completion and compilation checking in VS 2005 with it. I can also then query the role management system to retrieve an array of all the roles the current user belongs to and then databind this to the listbox control.

Since the MyProfile.aspx page requires a user to be logged in (otherwise retrieving profile information about them doesn’t make a lot of sense), I also added a <location> based authorization control tag in my web.config file:

<location path="MyProfile.aspx">

<system.web>

<authorization>

<deny users="?"/>

<allow users="*"/>

</authorization>

</system.web>

</location>

This is the same configuration I would have added in ASP.NET V1.1 – and basically tells the system to deny all users who aren’t logged in (the ? = anonymous), and then allow all users who are logged in (the * = all).

Those who aren’t logged in will get automatically re-directed to the login.aspx page. The <asp:login> control can be used there to allow users who have already registered to log-in without the developer having to write any custom code.

Summary

Hopefully this walks-through a fairly common real-world web app scenario and explains how it can be easily done in ASP.NET 2.0. The ASP.NET 2.0 Membership, Role and Profile system (especially when combined with the new login controls) pack a lot of productivity power.

What is really nice is that they are all built on the new ASP.NET 2.0 provider model. Our of the box ASP.NET ships built-in providers that provide Membership, Roles and Profile storage inside SQL Express, SQL Server and Active Directory stores (the later for Membership and Roles only). What is even better is that you can replace any of these implementations using a custom provider that you either buy or build yourself (see this blog post for more details on how to-do this). Replacing a provider in ASP.NET 2.0 simply involves changing a value in a web.config file – the above code sample will work regardless of what provider was plugged in (LDAP, Oracle, DB2, Custom SQL Table Schema, File-System, etc).

Hope this helps,

Scott

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据来源:中经数据库 主要指标110多个(全部都是纯粹的 市辖区 指标),大致是: GDP GDP增速 第一产业增加值占GDP比重 第二产业增加值占GDP比重 第三产业增加值占GDP比重 人均GDP 社会消费品零售总额 固定资产投资(不含农户) 新设外商投资企业数_外商直接投资 实际利用外资金额(美元) 一般公共预算收入 一般公共预算支出 一般公共预算支出_教育 一般公共预算支出_科学技术 金融机构人民币各项存款余额_个人储蓄存款 金融机构人民币各项存款余额 金融机构人民币各项贷款余额 规模以上工业企业单位数 规模以上工业企业单位数_内资企业 规模以上工业企业单位数_港澳台商投资企业 规模以上工业企业单位数_外商投资企业 规模以上工业总产值 规模以上工业总产值_内资企业 规模以上工业总产值_港澳台商投资企业 规模以上工业总产值_外商投资企业 规模以上工业企业流动资产合计 规模以上工业企业固定资产合计 规模以上工业企业利润总额 规模以上工业企业应交增值税 规模以上工业企业主营业务税金及附加 户籍人口数 年均户籍人口数 户籍人口自然增长率 第一产业就业人员占全部城镇单位就业人员比重 第二产业就业人员占全部城镇单位就业人员比重 第三产业就业人员占全部城镇单位就业人员比重 城镇非私营单位就业人员数 城镇非私营单位就业人员数_第一产业 城镇非私营单位就业人员数_第二产业 城镇非私营单位就业人员数_第三产业 城镇非私营单位就业人员数_农、林、牧、渔业 城镇非私营单位就业人员数_采矿业 城镇非私营单位就业人员数_制造业 城镇非私营单位就业人员数_电力、热力、燃气及水生产和供应业 城镇非私营单位就业人员数_建筑业 城镇非私营单位就业人员数_批发和零售业 城镇非私营单位就业人员数_交通运输、仓储和邮政业 城镇非私营单位就业人员数_住宿和餐饮业 城镇非私营单位就业人员数_信息传输、软件和信息技术服务业 城镇非私营单位就业人员数_金融业 城镇非私营单位就业人员数_房地产业 城镇非私营单位就业人员数_租赁和商务服务业 城镇非私营单位就业人员数_科学研究和技术服务业 城镇非私营单位就业人员数_水利、环境和公共设施管理业 城镇非私营单位就业人员数_居民服务、修理和其他服务业 城镇非私营单位就业人员数_教育 城镇非私营单位就业人员数_卫生和社会工作 城镇非私营单位就业人员数_文化、体育和娱乐业 城镇非私营单位就业人员数_公共管理、社会保障和社会组织 城镇非私营单位在岗职工平均人数 城镇就业人员数_私营企业和个体 城镇非私营单位在岗职工工资总额 城镇非私营单位在岗职工平均工资 城镇登记失业人员数 建成区面积 建设用地面积 建设用地面积_居住用地 液化石油气供气总量 液化石油气供气总量_居民家庭 人工煤气、天然气供气总量 人工煤气、天然气供气总量_居民家庭 液化石油气用气人口 人工煤气、天然气用气人口 城市公共汽电车运营车辆数 城市出租汽车运营车辆数 城市公共汽电车客运总量 道路面积 排水管道长度 建成区绿化覆盖面积 建成区绿化覆盖率 绿地面积 公园绿地面积 维护建设资金支出 土地面积 生活用水供水量 供水总量 全社会用电量 城乡居民生活用电量 工业生产用电量 房地产开发投资 房地产开发投资_住宅 限额以上批发和零售业法人单位数 限额以上批发和零售业商品销售总额 普通中学学校数 中等职业教育学校数 普通小学学校数 普通高等学校专任教师数 普通中学专任教师数 中等职业教育专任教师数 普通小学专任教师数 普通高等学校在校生数 普通中学在校生数 中等职业教育在校生数 普通小学在校生数 电视节目综合人口覆盖率 公共图书馆总藏量_图书 医疗卫生机构数_医院和卫生院 卫生人员数_执业(助理)医师 医疗卫生机构床位数_医院和卫生院 城镇职工基本养老保险参保人数 职工基本医疗保险参保人数 失业保险参保人数

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值