2

我快要发疯了,所以我会尝试再寻求一些帮助...我正在使用 Visual Studio Express 2012 for Web 创建一个使用 C# + MVC4 + Razor + Entity Framework + ASP.NET 的 Internet 项目4.5. 我需要执行以下操作:自动创建一个“管理员”用户(将在整个站点获得授权),然后创建一些用户角色。我已经阅读了有关 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 中,我将身份验证方法设置为 Forms(默认),并且还保留了默认连接字符串:

<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 控制的“About”页面。

7-我没有添加 EF 迁移或其他任何东西。默认情况下,所有其他内容都是 VS2012 自动创建的。所以我运行我的应用程序并单击“关于”链接,然后我会看到登录表单(这意味着 [Authorize(Roles = "Admins")] 注释正在执行预期的操作)。我尝试以 admin/123456 身份登录,但每次单击登录按钮时,登录页面都会一遍又一遍地重新加载。

我注意到了一些事情:

- 如果我在 Seed 方法中添加断点,它似乎没有被调用。

- 当我使用 DropCreateDatabaseAlways 并再次运行应用程序时,我能够以 admin/123456 身份登录,这让我再次想到我的整个 DataContextDbInitializer 类甚至没有被使用,因为我认为应该从头开始创建数据库,这将删除管理员用户。

我不知道还有什么要读的,还有什么要尝试的……我是 asp.net 的新手(需要我这么说吗?),简直要疯了。谢谢!!

4

3 回答 3

1

在 MVC4 中,默认的 Internet 应用程序具有内置的身份验证。一个名为的类InitializeSimpleMembershipAttribute位于 Filters 目录中。顾名思义,这个类初始化简单成员数据库。如果您查看构造函数,您将看到以下行:

 WebSecurity.InitializeDatabaseConnection("UserContext", "UserProfile", "UserId", "UserName", autoCreateTables: true);

在此行下方,您可以插入以下代码来创建默认用户:

// Create admin user.
                    if (!WebSecurity.UserExists("admin"))
                    {
                        WebSecurity.CreateUserAndAccount("admin", "12345678!");
                    }

只是另一种做事的方式。

于 2013-05-23T19:24:17.173 回答
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 中的 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 控制的“About”页面。哪个;)

谢谢您的帮助!它有助于我更多地了解正在发生的事情。

于 2013-01-28T11:05:47.537 回答
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
);
于 2013-01-27T14:26:51.803 回答