我快要疯了,所以我会再试一次帮助...... 我正在使用Visual Studio Express 2012 for Web使用C#+ MVC4 + Razor + Entity Framework + ASP.NET 4.5创建一个Internet项目。 我需要执行以下操作:自动创建“admin”用户(将在整个站点上授权),然后创建一些用户角色。 我已经阅读了关于SimpleMembership,角色和整个网络上所有内容的内容,但似乎没有什么能让我有一个直截了当的方法让整个过程发挥作用。
这是我到目前为止所做的:
1 - 创建了一个DataContext类:
public class DataContext : DbContext
{
public DataContext()
: base("DefaultConnection")
{
}
public DbSet<UserProfile> UserProfiles { get; set; }
}
2 - 创建了一个初始化类,我假设它会让我创建管理员用户和管理员角色:
public class DataContextDbInitializer : DropCreateDatabaseAlways<DataContext>
{
protected override void Seed(DataContext context)
{
var roles = (Webmatrix.WebData.SimpleRoleProvider)System.Web.Security.Roles.Provider;
var membership = (Webmatrix.WebData.SimpleMembershipProvider)System.Web.Security.Membership.Provider;
if (!roles.RoleExists("Admins")) {
roles.CreateRole("Admins");
}
if (membership.GetUser("admin", false) == null) {
membership.CreateUserAndAccount("admin", "123456");
}
if (!roles.GetRolesForUser("admin").Contains("Admins")) {
roles.AddUsersToRoles(new[] { "admin" }, new[] { "Admins" });
}
}
}
(我尝试从DropCreateDatabaseIfModelChanges继承,但这没有帮助。)
3 - 在Global.asax中为App_Start方法添加了两行:
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
Database.SetInitializer<DataContext>(new DataContextDbInitializer());
我也尝试在DataContextDbInitializer类的Seed方法中使用WebSecurity.InitializeDatabaseConnection,但是没有用。
4 - 从AccountController中删除了[InitializeSimpleMembership]注释,因此我可以从应用程序生命周期的最开始初始化它(使用App_Start中的WebSecurity.InitializeDatabaseConnection,正如我在3)。我尝试在HomeController中的Index方法之上添加[InitializeSimpleMembership]并从App_Start中删除WebSecurity.InitializeDatabaseConnection,但这也无济于事。
5 - 在Web.config中,我将身份验证方法作为表单(默认),并保留默认连接字符串:
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-TPFinal-20130121210447;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-TPFinal-20130121210447.mdf" providerName="System.Data.SqlClient" />
</connectionStrings>
并将其添加到system.web标记内:
<roleManager enabled="true" cacheRolesInCookie="true" />
6 - 然后,为了测试一切是否正常,我在HomeController的About()方法的顶部使用[Authorize(Roles =“Admins”)]注释。如果事情按预期工作,这应该迫使我以admin / 123456登录,以便能够看到由HomeController / About控制的“关于”页面。
7 - 我没有添加EF迁移或其他任何内容。默认情况下,所有其他内容都是VS2012自动创建的。 所以我运行我的应用程序,然后单击“关于”链接,我会看到登录表单(这意味着[Authorize(Roles =“Admins”)]注释正在执行预期的操作)。我尝试以admin / 123456身份登录,但每次单击登录按钮时,会反复重新加载登录页面。
我注意到的一些事情:
- 如果我在Seed方法中添加一个断点,它似乎没有被调用。
- 当我使用DropCreateDatabaseAlways再次运行应用程序时,我能够以admin / 123456身份登录,这让我再次想到我的整个DataContextDbInitializer类甚至没有被使用,因为我认为应该创建数据库从头开始,这将删除管理员用户。
我不知道还有什么要读的,还有什么可以尝试的......我是asp.net的新手(需要我这么说吗?)并且疯了。 谢谢!
答案 0 :(得分:1)
最后,我设法让整个事情发挥作用!
我的种子方法现在看起来像这样:
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
if (!Roles.RoleExists("Admins"))
{
Roles.CreateRole("Admins");
}
if (!WebSecurity.UserExists("admin"))
{
WebSecurity.CreateUserAndAccount("admin", "123456");
}
if (!Roles.GetRolesForUser("admin").Contains("Admins"))
{
Roles.AddUsersToRoles(new[] { "admin" }, new[] { "Admins" });
}
base.Seed(context);
Global.asax中的My App_Start如下所示:
Database.SetInitializer(new DataContextDbInitializer());
DataContext c = new DataContext();
c.Database.Initialize(true);
我不确定这是否真的在做什么,但我在Web.config中的system.web标记内有这个:
<roleManager enabled="true" cacheRolesInCookie="true" />
我还从AccountController中删除了[InitializeSimpleMembership],在AccountModels中删除了UsersContext类。我把这一点移到我自己的上下文类中:
public DbSet<UserProfile> UserProfiles { get; set; }
然后,为了测试一切是否正常,我在HomeController的About()方法的顶部使用[Authorize(Roles =“Admins”)]注释。如果事情按预期工作,这应该强制我以admin / 123456登录,以便能够看到由HomeController / About控制的“关于”页面。哪个;)
感谢您的帮助!这有助于我更多地了解正在发生的事情。
答案 1 :(得分:1)
在MVC4中,默认的Internet应用程序内置了身份验证。名为InitializeSimpleMembershipAttribute
的类位于Filters目录中。顾名思义,这个类初始化简单成员资格数据库。如果你看一下构造函数,你会看到以下行:
WebSecurity.InitializeDatabaseConnection("UserContext", "UserProfile", "UserId", "UserName", autoCreateTables: true);
在此行下方,您可以插入以下代码以创建默认用户:
// Create admin user.
if (!WebSecurity.UserExists("admin"))
{
WebSecurity.CreateUserAndAccount("admin", "12345678!");
}
另一种做事的方式。
答案 2 :(得分:0)
试试这样:
public class DataContextDbInitializer : DropCreateDatabaseAlways<DataContext>
{
protected override void Seed(DataContext context)
{
if (!Roles.RoleExists("Admins"))
{
Roles.CreateRole("Admins");
}
if (!WebSecurity.UserExists("admin"))
{
WebSecurity.CreateUserAndAccount("admin", "123456");
}
if (!Roles.GetRolesForUser("admin").Contains("Admins"))
{
Roles.AddUsersToRoles(new[] { "admin" }, new[] { "Admins" });
}
}
}
和您的Application_Start
:
Database.SetInitializer<DataContext>(new DataContextDbInitializer());
using (var ctx = new DataContext())
{
ctx.Database.Initialize(true);
}
WebSecurity.InitializeDatabaseConnection(
"DefaultConnection",
"UserProfile",
"UserId",
"UserName",
autoCreateTables: true
);