且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使用asp.net身份更新用户角色

更新时间:2023-02-26 08:23:17

的问题是,你的经理和DB没有使用相同的DbContext。所以,当你从数据库到管理范围内发送的用户将处理它作为一个新之一 - 那么你不能从角色中删除。你有两种方式去这里。最简单的是从你的经理获得用户。

  [HttpPost]
[ValidateAntiForgeryToken]
公共虚拟的ActionResult编辑(用户用户,串角色)
{
    如果(ModelState.IsValid)
    {
        //此行非常重要,
        VAR oldUser = Manager.FindById(user.Id);
        VAR oldRoleId = oldUser.Roles.SingleOrDefault()角色ID。
        VAR oldRoleName = DB.Roles.SingleOrDefault(R = GT; r.Id == oldRoleId).Name点;        如果(oldRoleName!=角色)
        {
            Manager.RemoveFromRole(user.Id,oldRoleName);
            Manager.AddToRole(user.Id,作用);
        }
        DB.Entry(用户).STATE = EntityState.Modified;        返回RedirectToAction(MVC.User.Index());
    }
    返回查看(用户);
}

更优雅的方式是开始使用像AutoFac(的DI-框架HTTPS://$c$c.google.com/p/autofac/wiki/MvcIntegration ),并设置您的DbContext为InstancePerApiRequest

builder.RegisterType<YourDbContext>().As<DbContext>().InstancePerApiRequest();

I have the following problem. While using the following code below to change the user's current role i am getting an exception with the message like below:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public virtual ActionResult Edit(User user, string role)
    {
        if (ModelState.IsValid)
        {
            var oldUser = DB.Users.SingleOrDefault(u => u.Id == user.Id);
            var oldRoleId = oldUser.Roles.SingleOrDefault().RoleId;
            var oldRoleName = DB.Roles.SingleOrDefault(r => r.Id == oldRoleId).Name;
            if (oldRoleName != role)
            {
                Manager.RemoveFromRole(user.Id, oldRoleName);
                Manager.AddToRole(user.Id, role);
            }
            DB.Entry(user).State = EntityState.Modified;

            return RedirectToAction(MVC.User.Index());
        }
        return View(user);
    }

Attaching an entity of type 'Models.Entities.User' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate.

Does anybody know a good solution to this problem ?

The problem is that your Manager and DB doesn't use the same DbContext. So when you send an user from the context of your DB to the Manager it will handle it as a "new" one - and then you cant remove it from the role. You have two ways to go here. The easiest is to get the User from your Manager.

[HttpPost]
[ValidateAntiForgeryToken]
public virtual ActionResult Edit(User user, string role)
{
    if (ModelState.IsValid)
    {
        // THIS LINE IS IMPORTANT
        var oldUser = Manager.FindById(user.Id);
        var oldRoleId = oldUser.Roles.SingleOrDefault().RoleId;
        var oldRoleName = DB.Roles.SingleOrDefault(r => r.Id == oldRoleId).Name;

        if (oldRoleName != role)
        {
            Manager.RemoveFromRole(user.Id, oldRoleName);
            Manager.AddToRole(user.Id, role);
        }
        DB.Entry(user).State = EntityState.Modified;

        return RedirectToAction(MVC.User.Index());
    }
    return View(user);
}

The more elegant way is to start using an DI-framework like AutoFac (https://code.google.com/p/autofac/wiki/MvcIntegration) and set your DbContext as InstancePerApiRequest.

builder.RegisterType<YourDbContext>().As<DbContext>().InstancePerApiRequest();