Łuk*_*wik 4 asp.net asp.net-mvc asp.net-mvc-5 asp.net-identity
我有以下问题.使用下面的代码更改用户的当前角色时,我收到如下消息的异常:
[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);
}
Run Code Online (Sandbox Code Playgroud)
附加"Models.Entities.User"类型的实体失败,因为同一类型的另一个实体已具有相同的主键值.如果图中的任何实体具有冲突的键值,则在使用"附加"方法或将实体的状态设置为"未更改"或"已修改"时,可能会发生这种情况.这可能是因为某些实体是新的并且尚未收到数据库生成的键值.在这种情况下,使用"添加"方法或"已添加"实体状态来跟踪图形,然后根据需要将非新实体的状态设置为"未更改"或"已修改".
有人知道这个问题的一个很好的解决方案吗?
Rik*_*ard 11
问题是您的Manager和DB不使用相同的DbContext.因此,当您将用户从数据库的上下文发送到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);
}
Run Code Online (Sandbox Code Playgroud)
更优雅的方式是开始使用像AutoFac这样的DI框架(https://code.google.com/p/autofac/wiki/MvcIntegration)并将DbContext设置为InstancePerApiRequest.
builder.RegisterType<YourDbContext>().As<DbContext>().InstancePerApiRequest();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13906 次 |
| 最近记录: |