简体   繁体   English

ASP.NET MVC 5页面挂起db调用

[英]ASP.NET MVC 5 page hangs on db call

I'm trying to get up and running with an MVC 5 project using ASP.NET Identity 2.0. 我正在尝试使用ASP.NET Identity 2.0启动并运行MVC 5项目。 My starting point is the example app in this tutorial . 我的出发点是本教程中的示例应用程序。 My initial page is Home/Index. 我的初始页面是Home / Index。 When I try to do a search (expecting a null return value) the app simply hangs and I can't figure out why. 当我尝试进行搜索(期望返回值为null)时,应用程序只会挂起,我无法弄清楚原因。 Instantiation of the db context is causing the Seed() method to be called, which seems normal, but then it hangs on the roleManager.FindByName(roleName) call (I've commented it in the code below). db上下文的实例化导致调用Seed()方法,这似乎正常,但它挂起在roleManager.FindByName(roleName)调用上(我在下面的代码中对它进行了评论)。 Pausing the debugger showed where it was stuck but I don't know where to go from there. 暂停调试器显示它被卡住但我不知道从那里去哪里。 Relevant classes are as follows. 相关课程如下。

Controller: 控制器:

public class HomeController : ApplicationController
{         
    public ActionResult Index()
    {
        var user = db.Users.Find("dummyVal");

        return View();
    }

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

        return View();
    }

    public ActionResult Contact()
    {
        ViewBag.Message = "Your contact page.";

        return View();
    }
}

Base Controller: 基础控制器:

public abstract class ApplicationController : Controller
{
    protected ApplicationDbContext db;

    public ApplicationController()
    {
        db = new ApplicationDbContext();
    }
}

DB Initializer: DB初始化器:

public class ApplicationDbInitializer : DropCreateDatabaseAlways<ApplicationDbContext> 
{
    protected override void Seed(ApplicationDbContext context) {
        InitializeIdentityForEF(context);
        base.Seed(context);
    }

    //Create User=Admin@Admin.com with password=Admin@123456 in the Admin role        
    public static void InitializeIdentityForEF(ApplicationDbContext db) {
        var userManager = HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>();
        var roleManager = HttpContext.Current.GetOwinContext().Get<ApplicationRoleManager>();
        const string name = "admin@example.com";
        const string password = "Admin@123456";
        const string roleName = "Admin";

        //Create Role Admin if it does not exist
        // EXECUTION HANGS ON THIS CALL...
        var role = roleManager.FindByName(roleName);
        if (role == null) {
            role = new IdentityRole(roleName);
            var roleresult = roleManager.Create(role);
        }

        var user = userManager.FindByName(name);
        if (user == null) {
            user = new ApplicationUser { UserName = name, Email = name };
            var result = userManager.Create(user, password);
            result = userManager.SetLockoutEnabled(user.Id, false);
        }

        // Add user admin to Role Admin if not already added
        var rolesForUser = userManager.GetRoles(user.Id);
        if (!rolesForUser.Contains(role.Name)) {
            var result = userManager.AddToRole(user.Id, role.Name);
        }

        // Create dummy user
        const string dummyUserName = "PeterVenkman";
        const string dummyUserPwd = "gf%^^ftf83X";

        var dummyUser = userManager.FindByName(dummyUserName);
        if (dummyUser == null) { 
            dummyUser = new ApplicationUser { UserName = dummyUserName, Email = dummyUserName };
            var result = userManager.Create(dummyUser, dummyUserPwd);
            result = userManager.SetLockoutEnabled(dummyUser.Id, false);
        }
    }
}

The error is because you are instantiating the dbContext object in the controller and not getting it from the owin context. 该错误是因为您在控制器中实例化dbContext对象而不是从owin上下文中获取它。 The presence of two different context objects one in the controller and one in the startup working on the same db is causing this deadlock. 控制器中存在两个不同的上下文对象,而同一个数据库中的一个启动工作正在导致此死锁。 Simplest way to resolve this is replace the code 解决此问题的最简单方法是替换代码

            db = new ApplicationDbContext();

with

db = System.Web.HttpContext.Current.GetOwinContext().Get<ApplicationDbContext>();

fixes the issue 解决了这个问题

I had the same problem and this is how I fixed it. 我遇到了同样的问题,这就是我修复它的方法。

  1. Delete your current database (I was using .mdf) 删除当前数据库(我使用的是.mdf)
  2. Create a new database 创建一个新数据库
  3. Clean and rebuild 清洁和重建
  4. Update database - if needed - 更新数据库 - 如果需要 -

Unfortunately, I do not know the source of the problem. 不幸的是,我不知道问题的根源。 Please edit the answer/post a comment if you know :) 如果你知道,请编辑答案/发表评论:)

For other people with the same issue, make sure the username/password in ApplicationDbInitializer are valid. 对于具有相同问题的其他人,请确保ApplicationDbInitializer中的用户名/密码有效。 It will hang if you set the admin password to 123 for example. 例如,如果您将管理员密码设置为123,它将挂起。

Edit: This post provides an explanation + answer http://forums.asp.net/post/5802779.aspx 编辑:这篇文章提供了解释+答案http://forums.asp.net/post/5802779.aspx

Suhas Joshi has the correct answer. Suhas Joshi有正确的答案。 The ApplicationDbContext object should be in essence a singleton that is managed by the "Microsoft ASPNET Identity Owin" package (installed using NuGet). ApplicationDbContext对象本质上应该是由“Microsoft ASPNET Identity Owin”包(使用NuGet安装)管理的单例。 When you manually create a new instance of it in your ApplicationController there is contention for the same resource causing this deadlock. 当您在ApplicationController中手动创建它的新实例时,会引发相同资源的争用,从而导致此死锁。

Note that the "Get()" extension used comes from the following library which you must have a reference to in your ApplicationContext class. 请注意,使用的“Get()”扩展名来自以下库,您必须在ApplicationContext类中引用它。

using Microsoft.AspNet.Identity.Owin; 

Thanks Suhas Joshi for pointing this out as it saved me greatly. 感谢Suhas Joshi指出这一点,因为它极大地拯救了我。 I would have just up-voted your answer, but unfortunately I don't have a strong enough reputation yet :). 我会对你的答案进行投票,但不幸的是我还没有足够强大的声誉:)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM