【问题标题】:Can't connect to Database to execute Identity functions无法连接到数据库以执行身份功能
【发布时间】:2014-02-05 21:01:25
【问题描述】:

我使用 ASP.NET MVC5 创建了一个新应用程序,使用个人用户帐户来确保安全性,并使用代码优先迁移来进行模型/数据库建模。所有选项都是默认的。

我想为其设置自定义用户和角色,所以我使用RoleManagerUserManager 创建了一个种子,只是为了填充数据库。它工作正常,创建 3 个用户、3 个角色并正确设置每个用户的角色。

我可以正确登录应用程序。问题是我无法使用任何 Identity 方法 User,即登录用户,我唯一能得到的是User.Identity.IsAuthenticated 值和User.Identity.Name,它们是正确的。像Roles.GetRolesForUser("John")User.IsInRole("Student") 这样的所有其他方法总是会产生这个异常:

ProviderException : 角色管理器功能尚未启用。

好吧,就像在this article 中一样,我设法在Web.config 中插入<roleManager enabled="true" />,现在它需要很长时间才能响应,并生成如下异常:

参考:

Roles.IsUserInRole("Student")

产生:

HttpException

参考:

Roles.GetRolesForUser(User.Identity.Name)

产生:

NullReferenceException

以学生角色登录的用户访问“关于”页面:

[Authorize(Roles="Teacher")]
public ActionResult About()
{
    ViewBag.Message = "Your application description page.";

    return View();
}

产生:

SqlException
HttpException

就像我根本没有连接到数据库,这是 LocalDB,自动生成的,我可以填充种子方法,甚至登录到应用程序。

我什至可以从 AspNetUsers 表中加载数据并使用以下代码将其显示在视图中:

using (Models.ApplicationDbContext db = new Models.ApplicationDbContext())
{
    List<Models.ApplicationUser> Users = db.Users.ToList();

    ViewBag.Users = Users;
}

return View();

请帮忙:'(


这是种子代码,它可以正常工作,因此它可以使用身份引擎连接到数据库。

protected override void Seed(LocalBDAuthTest.Models.ApplicationDbContext context)
{
    #region Create Roles Student, Teacher e Administrator

    var RoleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));

    // Student
    if (!RoleManager.RoleExists("Student"))
    {
        RoleManager.Create(new IdentityRole("Student"));
    }

    // Teacher
    if (!RoleManager.RoleExists("Teacher"))
    {
        RoleManager.Create(new IdentityRole("Teacher"));
    }

    // Administrator
    if (!RoleManager.RoleExists("Administrator"))
    {
        RoleManager.Create(new IdentityRole("Administrator"));
    }

    #endregion

    #region Create Users for Student, Teacher e Administrator Roles.

    var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));


    // Create a Student user and set it's role to Student
    if (!context.Users.Any(u => u.UserName == "John"))
    {
        var Student = new ApplicationUser() { UserName = "John" };
        var Result = UserManager.Create(Student, "123456");
    }
    if (!UserManager.FindByName("John").Roles.Any())
    {
        UserManager.AddToRole(UserManager.FindByName("John").Id, "Student");
    }


    // Create a Teacher user and set it's role to Teacher
    if (!context.Users.Any(u => u.UserName == "Arnold"))
    {
        var Teacher = new ApplicationUser() { UserName = "Arnold" };
        var Result = UserManager.Create(Teacher, "123456");
        UserManager.AddToRole(Teacher.Id, "Teacher");
    }
    if (!UserManager.FindByName("Arnold").Roles.Any())
    {
        UserManager.AddToRole(UserManager.FindByName("Arnold").Id, "Teacher");
    }


    // Create a Administrator user and set it's role to Administrator
    if (!context.Users.Any(u => u.UserName == "Caroline"))
    {
        var Administrator = new ApplicationUser() { UserName = "Caroline" };
        var Result = UserManager.Create(Administrator, "123456");
        UserManager.AddToRole(Administrator.Id, "Administrator");
    }
    if (!UserManager.FindByName("Caroline").Roles.Any())
    {
        UserManager.AddToRole(UserManager.FindByName("Caroline").Id, "Administrator");
    }

    #endregion
    }

【问题讨论】:

    标签: authentication migration asp.net-mvc-5 localdb


    【解决方案1】:

    这是由于混合了 ASP.NET 身份和 ASP.NET 成员身份,这样做:

    <system.web>
        <roleManager enabled="true" />
    </system.web>
    

    您启用了成员资格 SqlRoleProvider,它使用您网站 \app_dir 文件夹中数据库中默认 SQL Express 实例中的角色存储。

    如果你打开你的 machine.config,你会发现:

    <connectionStrings>
      <add name="LocalSqlServer" 
        connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;
          AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true"
          providerName="System.Data.SqlClient"/>
    </connectionStrings>
    .
    .
    .
    <roleManager>
      <providers>
        <add name="AspNetSqlRoleProvider" connectionStringName="LocalSqlServer" ...
    </providers>
    </roleManager>
    

    您很可能没有安装 SQL Express,这就是您遇到超时和 SQL 异常的原因。

    对于 ASP.NET 标识,不要使用 System.Web.Security.Roles(它是 ASP.NET 成员资格的一部分),而是使用 Microsoft.AspNet.Identity.RoleManager

    【讨论】:

    • 该死,你是对的!我从 Web.config 中擦除了 roleManager。现在它只剩下数据库连接错误。如果我将 [Authorize(Roles = "rolename")] 放在某个动作中,然后转到该动作的视图,我得到很长时间的超时,并且在漫长的等待之后,SqlExceptions 和 HttpExceptions,说它们无法连接到数据库.这怎么可能?我在它的最新版本中使用 LocalDB,它已经安装,连同 SQL Express 和 Visual Studio 2013 Ultimate,应该是整个包都附带的,对吧?
    • 不确定您的确切设置,请重新检查您的 web.config 连接字符串,并重新检查您的代码以了解正在使用的连接密钥。它一定是你修改过的东西!
    • 另请注意,Authorize 属性不应该命中数据库,它对当前HttpContext 中的IPrincipal 用户进行操作,并迭代存储在其中的角色声明。
    • Ops,我仍然有 不知何故......钉了它!我修好了,现在我又可以把头发放回头上了,哈哈,谢谢兄弟!
    • 很遗憾,由于我的声誉,我不能只投票给你的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-14
    • 2022-08-23
    • 2013-06-17
    相关资源
    最近更新 更多