使用SimpleMembership和EF模型优先

Bob*_*lth 24 entity-framework simplemembership

可以SimpleMembership与使用EF模型的第一?当我尝试它时,我打电话时"无法找到所请求的.NET Framework数据提供程序"WebSecurity.InitializeDatabaseConnection.

换句话说:WebSecurity.InitializeDatabaseConnection当连接字符串使用System.Data.EntityClient提供者时,我无法接受调用(就像使用模型优先范例时那样).

要重新解决此问题,请创建一个MVC 4应用程序,并使用您在实体设计器中创建的模型优先用户类替换代码优先的 UserProfile实体类(使用MVC 4模板免费获得):

  1. VS 2012中创建一个MVC 4应用程序并添加一个新的空白实体数据模型.
  2. 添加一个名为User模型的新实体,其中包含字段Id, UserName, and FullName.因此,此时,User数据实体被映射到Users表,并通过使用System.Data.EntityClient提供程序的时髦连接字符串进行访问.
  3. 验证EF是否可以访问User实体.一种简单的方法是基于User表及其关联的DbContext构建一个Users控制器.
  4. 编辑该AccountModels.cs文件以删除UserProfile该类及其关联的UsersContext类.使用对新User类及其关联类的引用替换对(现在缺少的)UserProfileUsersContext类的引用DbContext.
  5. Move the call to InitializeDatabaseConnection from the InitializeSimpleMembershipAttribute filter class to the Application_Start method in Global.asax.cs. While you're at it, modify the arguments to use your new User entity's connection string, table name, and UserId column name.
  6. Delete the (no longer used) InitializeSimpleMembershipAttribute class and the references to it.

When you run the repro, it will get an Exception at the call to InitializeDatabaseConnection.

Bob

Mar*_*ric 24

SimpleMembership可以首先使用模型.这是解决方案.

1. InitializeSimpleMembershipAttribute.cs从MVC 4 Internet应用程序模板应该是这样的

namespace WebAndAPILayer.Filters
{
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public sealed class InitializeSimpleMembershipAttribute : ActionFilterAttribute
    {
        private static SimpleMembershipInitializer _initializer;
        private static object _initializerLock = new object();
        private static bool _isInitialized;

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            // Ensure ASP.NET Simple Membership is initialized only once per app start
            LazyInitializer.EnsureInitialized(ref _initializer, ref _isInitialized, ref _initializerLock);
        }

        private class SimpleMembershipInitializer
        {
            public SimpleMembershipInitializer()
            {
                try
                {
                    WebSecurity.InitializeDatabaseConnection("ConnStringForWebSecurity", "UserProfile", "Id", "UserName", autoCreateTables: true);
                }
                catch (Exception ex)
                {
                    throw new InvalidOperationException("Something is wrong", ex);
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

2.删除CodeFirst类 AcountModel.cs

3.Fix AccountCotroler.cs与您的模型第一次的DbContext(工作ExternalLoginConfirmation(RegisterExternalLoginModel model, string returnUrl)方法)

4.定义你的"ConnStringForWebSecurity"连接字符串,该字符串与用于模型优先的数据库访问的那个时髦conn字符串不同,请注意我们使用的System.Data.SqlClient不是提供者System.Data.EntityClient

 <connectionStrings>
         <add name="ModelFirstEntityFramework" connectionString="metadata=res://*/Context.csdl|res://*/Context.ssdl|res://*/Context.msl;provider=System.Data.SqlClient;provider
 connection string=&quot;data source=.\SQLEXPRESS;Initial
 Catalog=aspnet-MVC4;Integrated
 Security=SSPI;multipleactiveresultsets=True;App=EntityFramework&quot;"
 providerName="System.Data.EntityClient" />
         <add name="ConnStringForWebSecurity" connectionString="data source=.\SQLEXPRESS;Initial Catalog=aspnet-MVC4;Integrated
 Security=SSPI" providerName="System.Data.SqlClient" />
       </connectionStrings>
Run Code Online (Sandbox Code Playgroud)

  • 谢谢马里奥!这引发了两个关于两个DbContext连接如何相互合作的问题.我将为这两个问题创建新的论坛主题. (2认同)
  • 双连接字符串是我在DbFirst中缺少的部分!因此,SimpleMembershipProvider助手只能使用经典连接字符串,而不能使用EF连接字符串. (2认同)

Cra*_*ntz 12

这是MVC 4中的一个错误.这篇博文中有一个解决方法.

作为动作过滤器,InitializeSimpleMembershipAttribute挂钩OnActionExecuting进行延迟初始化工作,但这在生命周期中可能为时已晚.如果需要执行基于角色的访问检查(期间OnAuthorization),则Authorize属性将需要提供者提前准备好.换句话说,如果对站点的第一个请求命中控制器操作,如下所示:

[Authorize(Roles="Sales")]
Run Code Online (Sandbox Code Playgroud)

..然后你会有一个例外,因为过滤器检查用户的角色,但提供程序没有初始化.

我的建议是从项目中删除ISMA,并在应用程序启动事件期间初始化WebSecurity.


LeL*_*g37 10

1 - 您需要启用迁移,尤其是使用EntityFramework 5

2 - 移动你的

WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "EmailAddress", autoCreateTables: true); 
Run Code Online (Sandbox Code Playgroud)

您的YourMvcApp/Migrations/Configuration.cs类中的Seed方法

    protected override void Seed(UsersContext context)
    {
        WebSecurity.InitializeDatabaseConnection(
            "DefaultConnection",
            "UserProfile",
            "UserId",
            "UserName", autoCreateTables: true);

        if (!Roles.RoleExists("Administrator"))
            Roles.CreateRole("Administrator");

        if (!WebSecurity.UserExists("lelong37"))
            WebSecurity.CreateUserAndAccount(
                "lelong37",
                "password",
                new {Mobile = "+19725000000", IsSmsVerified = false});

        if (!Roles.GetRolesForUser("lelong37").Contains("Administrator"))
            Roles.AddUsersToRoles(new[] {"lelong37"}, new[] {"Administrator"});
    }
Run Code Online (Sandbox Code Playgroud)

现在EF5将负责创建UserProfile表,在这样做之后,您将调用WebSecurity.InitializeDatabaseConnection以仅使用已创建的UserProfile表注册SimpleMembershipProvider (在您的情况下,您可以将"UserProfile"参数值替换为您的自定义表name),同时tellling SimpleMembershipProvider哪一列是UserId和UserName.我还展示了一个示例,说明如何添加用户,角色并将Seed方法中的两者与自定义UserProfile属性/字段相关联,例如用户的Mobile(数字).

3 - 现在,当您从Package Manager控制台运行update-database时,EF5将为您的表配置所有自定义属性

有关其他参考资料,请参阅本文的源代码:http: //blog.longle.net/2012/09/25/seeding-users-and-roles-with-mvc4-simplemembershipprovider-simpleroleprovider-ef5-codefirst-and-custom -user的属性/