ASP.NET MVC5从多个实例访问一个对象

时间:2014-04-03 10:10:43

标签: c# asp.net asp.net-mvc asp.net-mvc-4 asp.net-mvc-5

我有以下代码,它在使用C#ASP.NET MVC5的Web应用程序中使用

// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
    if (ModelState.IsValid)
    {
        var Db = new ApplicationDbContext();
        var user = await UserManager.FindAsync(model.UserName, model.Password);
        if (user != null)
        {
            await SignInAsync(user, model.RememberMe);

            user.LastLogin = DateTime.UtcNow;
            Db.Entry(user).State = System.Data.Entity.EntityState.Modified;
            await Db.SaveChangesAsync();
            return RedirectToLocal(returnUrl);
        }
        else
        {
            ModelState.AddModelError("", "Invalid username or password.");
        }
    }

    // If we got this far, something failed, redisplay form
    return View(model);
}

我想要做的是使用同一个对象来完成两个不同的任务:  1.登录验证  2.更新对象的数据。数据保存在SQL Server数据库中。

上面的代码抛出一个异常,说:

An entity object cannot be referenced by multiple instances of IEntityChangeTracker.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: An entity object cannot be referenced by multiple instances of IEntityChangeTracker.

有谁知道我应该如何缓解这种情况?

编辑#1 这就是我的构造函数的样子。

public AccountController(): this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())))
{

}

public AccountController(UserManager<ApplicationUser> userManager)
{
    UserManager = userManager;
}

2 个答案:

答案 0 :(得分:0)

好的,我找到了解决方案

我所做的是分配不同的对象。并在单独的上下文中使用该对象。

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
    {
        if (ModelState.IsValid)
        {
            var Db = new ApplicationDbContext();

            var user = await UserManager.FindAsync(model.UserName, model.Password);
            if (user != null)
            {
                await SignInAsync(user, model.RememberMe);

                var temp = Db.Users.Find(user.UserName);
                temp.LastLogin = DateTime.UtcNow;
                Db.Entry(temp).State = EntityState.Modified;
                await Db.SaveChangesAsync();

                return RedirectToLocal(returnUrl);
            }
            else
            {
                ModelState.AddModelError("", "Invalid username or password.");
            }
        }

        // If we got this far, something failed, redisplay form
        return View(model);
    }

答案 1 :(得分:0)

您已经有一个要传递到UserStore的上下文。您可以重用它,而不必处理多个上下文。

public class AccountController : Controller
{
    public AccountController ()
    {
        Context = new ApplicationDbContext()
        UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(Context));
    }

    protected ApplicationDbContext Context { get; private set; }

    protected UserManager<User> UserManager { get; private set; }
}

现在只需使用Context来获取对数据库的引用。我还建议您查看一个BaseController类来保留它以供重用,并使用Unit of Work模式来保存您的上下文。

相关问题