介绍System.Web.Providers- ASP.NET通用提供程序在SQL Compact数据库和SQL Azure数据库上的会话、成员资格、角色和用户配置文件


[原文发表地址]Introducing System.Web.Providers - ASP.NET Universal Providers for Session, Membership, Roles and User Profile on SQL Compact and SQL Azure

[原文发表时间]2011-06-16 03:47 下午

我常常提醒人们ASP.NET > (ASP.NET MVC + ASP.NET WebForms)这个公式。整个ASP.NET的“金字塔底部”有很多在应用程序中能用到的东西。包括会话状态、成员资格(用户)、角色、配置文件数据和其下的提供程序模型等。并不是每个人都能运用到上述的东西,但是它们对很多应用程序都很适用,甚至大如ASP.NET网站本身也会受用。

现在,Web平台和工具队伍(WPT)正在发布ASP.NET Universal Providers内部测试版,用来扩展会话、成员资格、角色和用户配置文件对SQL Compact Edition 和 SQL Azure的支持。ASP.NET Universal Providers除了支持额外的存储选项外,它的工作方式和现有的SQL-based providers很相似.

Crazy random logo of evocative clipart combining the .NET Logo and some universal powerplugs into an unofficial logo

现在Universal Providers正通过NuGet Package发布,而且很有可能成为ASP.NET下一个版本的默认程序。

为了启用这些提供程序,NuGet 软件包在web.config 文件里增加了配置项。这些提供程序的配置和现有的SqlMembershipProvider类相同。但是它的类型参数是按照新的设置,如下表所示

SQL Provider Types

System.Web.Security.SqlMembershipProvider

System.Web.Profile.SqlProfileProvider

System.Web.Security.SqlRoleProvider

Equivalent Type for Universal Providers

System.Web.Providers.DefaultMembershipProvider

System.Web.Providers.DefaultProfileProvider

System.Web.Providers.DefaultRoleProvider

如果你安装了这些,NuGet软件包会在web.config文件中交换你的默认提供程序 。当然你也可以一一选择这些设置。现在我们改变一下Profile,Membership, RoleManager 和 SessionState。后者比前者更佳,因为它能更好的允许你的session-state-using Azure 应用程序随着作为后端存储的SQL Azure的大小而变化。

Install-Package System.Web.Providers

使用这些通用的“Default Profile Providers意味着你所要做的一切就是设置正确的连接字符串,并且确保用到这些服务的应用程序要与SQL Server(plus Express)SQL Server Compact SQL Azure保持一致,不能随意改代码

 1: <configuration>

 2: <connectionStrings>

 3: <add name="DefaultConnection" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\aspnet.mdf;Initial Catalog=aspnet;Integrated Security=True;User Instance=True;MultipleActiveResultSets=True" providerName="System.Data.SqlClient"/>

 4: </connectionStrings>

 5: <system.web>

 6: <profile defaultProvider="DefaultProfileProvider" >

 7: <providers>

 8: <add name="DefaultProfileProvider" type="System.Web.Providers.DefaultProfileProvider" connectionStringName="DefaultConnection" applicationName="/"/>

 9: </providers>

 10: </profile>

 11: <membership defaultProvider="DefaultMembershipProvider">

 12: <providers>

 13: <add name="DefaultMembershipProvider" type="System.Web.Providers.DefaultMembershipProvider" connectionStringName="DefaultConnection" 

 14: enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false"

 15: maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10"

 16: applicationName="/" />

 17: </providers>

 18: </membership>

 19: <roleManager defaultProvider="DefaultRoleProvider">

 20: <providers>

 21: <add name="DefaultRoleProvider" type="System.Web.Providers.DefaultRoleProvider" connectionStringName="DefaultConnection" applicationName="/" />

 22: </providers>

 23: </roleManager>

 24: <sessionState mode="Custom" customProvider="DefaultSessionProvider">

 25: <providers>

 26: <add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider" connectionStringName="DefaultConnection" applicationName="/"/>

 27: </providers>

 28: </sessionState>

 29: </system.web>

 30: </configuration>

选择一个数据存储

默认情况下,NuGet软件包通过设置连接字符串来使用SQL Server Express数据库(包装在这里以增加可读性)

"Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\aspnetdb.mdf;
Initial Catalog=aspnet;Integrated Security=True;
User Instance=True;MultipleActiveResultSets=True" providerName="System.Data.SqlClient"

如果你想使用SQL Server Compact,按照下例所示修改连接字符串。

1: <connectionStrings> 2: <add name="Sql_CE" connectionString="Data Source=|DataDirectory|\MyWebSite.sdf;" 3: providerName="System.Data.SqlServerCe.4.0"/> 4: </connectionStrings>
如果你想使用SQL Azure,按照下例所示修该连接字符串(概括起来以增加可读性)
1: <connectionStrings> 2: <add name="Sql_Azure" 3: connectionString

="data source=myDNSName;Initial Catalog=myDatabase;

4: User ID=myUserName;Password=myPassword; 5: Encrypt=true;Trusted_Connection=false; 6: MultipleActiveResultSets=True" 7: providerName="System.Data.SqlClient"/> 8: <connectionStrings>

尽管这项发布主要是为了扩展对SQL Server所有版本的支持,我觉得你们可能甚至不知道这些东西是用来做什么的。所以我要花点时间解释它。我注意到大家对StackOverflow和其他类似ASP.NET MVC的一些网站上使用Membership 和 Profile有疑惑, 所以下面我会举例来解释它:

以ASP.NET MVC (with the Universal Providers)上的成员资格,角色和配置文件为例
我会先在在新的ASP.NET MVC 3 Projec上启动VS和File | New Project。然后相应地右击“Reference”选项,选择Add | Library Reference。NuGet 包id是”System.Web.Providers."装好这个软件包后,如果需要的话,我还可以通过NuGet安装SQL Compact 版本,按照上述所示设置SQL Compact 的连接字符串。
记住,这只是一个功能测试版,可能会有bugs(请汇报它们)。以便在ASP.NET的下一个版本发布前进行几次更新。

首先,运行应用程序,单击Register,创建一个新的用户名”Scott.”

 
 
 
Making a new user
 
 

给用户添加角色

第二步,选择Visual Studio里菜单项中的Project选项,访问ASP.NET Configuration选项。(如果愿意的话,也可以输入自己的admin 部分,然后以编程方式来完成这个操作。)

 
Selecting ASP.NET Configuration site from the Project Menu
 

然后在Security标签的“Roles下创建一个新的角色:

 
image
 

然后找到”Scott"用户,把它添加到“Administrator Role”中:

Giving the Scott User Administrator Role

我要演示一下以确认用户是否是“管理员”。先添加一部分代码到默认网站下的_LogOnPartial. Cshtml中,我们会看到[Administrator]和其用户名是挨着的。

接着我再增添一行"User.IsInRole(),如下所示

 1: @if(Request.IsAuthenticated) {

 2: <text>Welcome <strong>@User.Identity.Name</strong> 

 3: @(User.IsInRole("Administrator") ? "(Administrator)" : String.Empty) 

 4: [ @Html.ActionLink("Log Off", "LogOff", "Account") ]</text>

 5: }

 6: else {

 7: @:[ @Html.ActionLink("Log On", "LogOn", "Account") ]

 8: }

 9: @if (ViewBag.Profile != null) { 

 10: <text>Hey, your birthday is @ViewBag.Profile.Birthdate.ToString("d")! Congrats.</text>

 11: }

现在我可以指派一些角色给用户,然后进行核对。我可以任意设置角色,比如Bronze, Silver, Gold,等。

给用户添加配置文件信息

如果我想给用户一个Birthday属性 , 想将其变成用户配置文件里的一部分。我可以使用配置文件对象,通过字符串获得:

然而,对于配置文件,我或许可以使用一个更强类型语法。

注意:我已经提出过这个问题,就是用户在MVC3中阻塞在控制器上但是配置文件却很容易丢失。或许在MVC4中可以被修复。我相信只是一时疏忽而已。如果你想让你的代码更易测试的话,就不用去对HttpContext 刨根问底了。

创建一个小的自定义配置文件扩展profileBase, :

 1: public class MyCustomProfile : ProfileBase

 2: {

 3: public DateTime? Birthdate { 

 4: get { return this["Birthdate"] as DateTime?; }

 5: set { this["Birthdate"] = value; }

 6: }

 7: }

 8:  

同时,我也可以把"getting”放在静态自定义类下的配置文件中,或使用依赖注入。这取决你想通过什么方法获得。

 1: public static MyCustomProfile GetUserProfile(string username)

 2: {

 3: return Create(username) as MyCustomProfile;

 4: }

 5: public static MyCustomProfile GetUserProfile()

 6: {

 7: return Create(Membership.GetUser().UserName) as MyCustomProfile;

 8: }

然后在web.config上,我会更新<profile>,以便系统能知道当我需要的时候想要用的派生配置文件类。

 1: <profile defaultProvider="DefaultProfileProvider" inherits="MvcApplication46.Models.MyCustomProfile">

 2: ...

对于老版的网站项目,我会在web.config增加一些新属性。可以使用SettingsAllowAnonymous 属性来写代码中的自定义派生类。

 1: ..

 2: </providers>

 3: <properties>

 4: <add allowAnonymous="false" defaultValue="" name="Birthdate" readOnly="false" serializeAs="String" type="System.DateTime" />

 5: </properties>

或者,我也可以使用IIS7的管理用户界面来编辑web.config中的详细配置文件。你可以使用配置文件的所有不同类型的属性,对它们进行分类,这些你都可以操作。

Using IIS Manager to edit User Profile schema

如果需要的话,我可以要求用户配置文件(我已经将其设置为仅为经过身份验证的用户),同时设为默认的。我是手动保存的,也有自动保存选项。

 1: if (User.Identity.IsAuthenticated)

 2: {

 3: var customProfile = HttpContext.Profile as MyCustomProfile;

 4: DateTime? birthday = customProfile.Birthdate; //Because I made a strongly typed derived class

 5: if (!birthday.HasValue) {

 6: customProfile.Birthdate = new DateTime(1965, 1, 14); //cause that's everyone's birthday, right?

 7: customProfile.Save(); //or set autosave if you like.

 8: }

 9: ViewBag.Profile = customProfile; //So the View can use it

 10: }

最后,把配置文件放进ViewBag以便其能从View进行访问。也可以把自己想要的东西添加到更大的ViewModel中。随后我就可以在完整性检查的情况下使用它了。

 1: @if (ViewBag.Profile != null) { 

 2: @:Hey, your birthday is @ViewBag.Profile.Birthdate.ToString("d")! Congrats.

 3: }

希望在其下来的几个月里可以看到更多的象这样的cloud-ready 的东西。我会更好得把你的应用程序,(不论新旧)放到Azure甚至SQL Compact上。希望这篇博客对你们所帮助。希望你们能够喜欢!


Comments (0)

Skip to main content