SimpleMembership 可以与 EF型号优先一起使用吗?当我尝试它时,当我调用WebSecurity.InitializeDatabaseConnection.
换句话说:当连接字符串使用WebSecurity.InitializeDatabaseConnection
提供程序时,我无法调用System.Data.EntityClient
(就像使用 model-first <时一样) / strong>范例)。
要重新解决此问题,请创建一个MVC 4应用,并使用模型优先替换代码优先 UserProfile实体类(使用MVC 4模板免费获得) 您在实体设计器中创建的用户类:
User
的新实体,其中包含Id,
的字段
UserName, and FullName
。那么,此时,User
数据实体就是
映射到Users
表,可通过时髦的连接访问
使用System.Data.EntityClient
提供程序的字符串。User
实体。一个简单的方法
那就是基于User表来构建一个Users控制器
及其相关的DbContext。AccountModels.cs
文件以删除UserProfile
类和
其关联的UsersContext
类。替换对的引用
(现在缺少)带引用的UserProfile
和UsersContext
类
到您的新用户类及其关联的DbContext
类。InitializeSimpleMembershipAttribute
类及其引用。当你运行repro时,在调用InitializeDatabaseConnection.
鲍勃
答案 0 :(得分:24)
SimpleMembership可以先使用模型。这是解决方案。
来自MVC 4 Internet Application模板的 1。InitializeSimpleMembershipAttribute.cs
应如下所示
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);
}
}
}
}
}
2.删除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="data source=.\SQLEXPRESS;Initial
Catalog=aspnet-MVC4;Integrated
Security=SSPI;multipleactiveresultsets=True;App=EntityFramework""
providerName="System.Data.EntityClient" />
<add name="ConnStringForWebSecurity" connectionString="data source=.\SQLEXPRESS;Initial Catalog=aspnet-MVC4;Integrated
Security=SSPI" providerName="System.Data.SqlClient" />
</connectionStrings>
答案 1 :(得分:12)
这是MVC 4中的一个错误。There's a workaround in this blog post。
作为动作过滤器,
InitializeSimpleMembershipAttribute
挂钩到OnActionExecuting
以执行延迟初始化工作,但这在生命周期中可能为时已晚。如果需要执行基于角色的访问检查(在OnAuthorization
期间),Authorize属性将需要提供者提前准备好。换句话说,如果对站点的第一个请求命中控制器操作,如下所示:
[Authorize(Roles="Sales")]
..然后你会有一个例外,因为过滤器会检查用户的角色,但是提供程序没有初始化。
我的建议是从项目中删除ISMA,并在应用程序启动事件期间初始化WebSecurity。
答案 2 :(得分:10)
1 - 您需要启用迁移,特别是使用EntityFramework 5
2 - 移动你的
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "EmailAddress", autoCreateTables: true);
到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"});
}
现在EF5将负责创建您的UserProfile表,在这样做之后,您将调用WebSecurity.InitializeDatabaseConnection以仅使用已创建的UserProfile表注册SimpleMembershipProvider(在您的情况下,您可以替换“UserProfile”带有自定义表名的参数值),也可以通过Tellling SimpleMembershipProvider列中的UserId和UserName。我还展示了如何添加用户,角色并将Seed方法中的两者与自定义UserProfile属性/字段相关联的示例,例如用户的手机(号码)。
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-properties/ 强>
答案 3 :(得分:1)
由WebSecurity.InitializeDatabaseConnection
引起的此问题无法将连接字符串与System.Data.EntityClient
提供程序名称一起使用。
提供双连接字符串听起来不太好,因此您可以首先在分部类的构造函数中为EF模型生成连接字符串。
代码看起来像是吼叫
public partial class MyDataContext
{
private static string GenerateConnectionString(string connectionString)
{
var cs = System.Configuration.ConfigurationManager
.ConnectionStrings[connectionString];
SqlConnectionStringBuilder sb =
new SqlConnectionStringBuilder(cs.ConnectionString);
EntityConnectionStringBuilder builder =
new EntityConnectionStringBuilder();
builder.Provider = cs.ProviderName;
builder.ProviderConnectionString = sb.ConnectionString;
builder.Metadata = "res://*/MyDataContext.csdl|" +
"res://*/MyDataContext.ssdl|res://*/MyDataContext.msl";
return builder.ToString();
}
public MyDataContext(string connectionName) :
base(GenerateConnectionString(connectionName)) { }
}
使用这个技巧你可以在你的web配置上使用单个连接字符串,但是你不能在datacontext上使用默认构造函数的一个问题,而是在实例化datacontext时你应该在任何地方设置连接字符串名称。但是当你使用依赖注入模式时,这不是一个大问题。
答案 4 :(得分:0)
我无法使用EF和WebMatrix webSecurity类,以避免此问题并继续:
首先将我的Ef模型更改为代码。
更改连接字符串以使用providerName =“System.Data.SqlClient”(删除所有元数据信息)或使用EF连接
在我的情况下,模型,数据和网络是不同的项目,因此对于我而言,从web.project上的web.config中删除此信息不是问题。
现在websecuroty.initializedatabase没有使用EF连接字符串运行。
我希望这有帮助