更新用户商店标识框架3.0

Jka*_*kal 1 c# asp.net-mvc entity-framework asp.net-identity

我几天来一直在寻找解决方案,只找到与旧版Identity Framework相关的答案.

项目使用c#Asp.net MVC 6 Entity Framework 7 beta8和Identity Framework 3.0.0-beta Code-First Data.在一个简单的项目中,我正在尝试实现仅限管理员的用户信息/编辑器页面,该页面允许通过访问UserStore或UserManager来编辑所有用户属性,并将更改保存到DBcontext中的标准Identity Framework用户存储中.

这是带有额外字段的ApplicationUser Model代码:

public class ApplicationUser : IdentityUser
{
    [Display(Name = "Last Name")]
    [DataType(DataType.Text)]
    [StringLength(50)]
    public string UserLastName { get; set; }

    [Display(Name = "First Name")]
    [DataType(DataType.Text)]
    [StringLength(50)]
    public string UserFirstName { get; set; }

    [Display(Name = "User")]
    public override string UserName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

Index视图的相应Controller代码:

public class UserListController : Controller
{
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly SignInManager<ApplicationUser> _signInManager;

    public UserListController(UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager)
    {
        _userManager = userManager;
        _signInManager = signInManager;
    }

    // GET: Index
    public IActionResult Index()
    {
        var userStore = new UserStore<ApplicationUser>(new ApplicationDbContext());

        var listofUsers = userStore.Users.ToList();

        if (listofUsers == null)
        {
            return new HttpStatusCodeResult(404);
        }

        return View(listofUsers);
    }
Run Code Online (Sandbox Code Playgroud)

索引视图有一个编辑操作,用于传递所选用户的ID:

@Html.ActionLink("Edit", "Edit", new { id = item.Id })
Run Code Online (Sandbox Code Playgroud)

以及Controller代码的其余部分:

    // GET: Edit
    [HttpGet]
    public IActionResult Edit(Guid? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(404);
        }
        var userStore = new UserStore<ApplicationUser>(new ApplicationDbContext());

        ApplicationUser userforEdit = userStore.Users.SingleOrDefault(x => x.Id == id.ToString());

        if (userforEdit == null)
        {
            return new HttpStatusCodeResult(404);
        }
        return View(userforEdit);
    }


    // POST: Edit
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Edit(ApplicationUser editedUser)
    {
        if (ModelState.IsValid)
        {
            var UpdateUserResult = await _userManager.UpdateAsync(editedUser);

            return RedirectToAction("Index");
        }
        return View(editedUser);
    }
}
Run Code Online (Sandbox Code Playgroud)

}

执行期间出现错误异常

var UpdateUserResult = await _userManager.UpdateAsync(editedUser);
Run Code Online (Sandbox Code Playgroud)

InvalidOperationException:无法跟踪实体类型"UserManagement.Models.ApplicationUser"的实例,因为已经跟踪了具有相同键的此类型的另一个实例.对于新实体,请考虑使用IIdentityGenerator生成唯一键值.

我部分理解了两次实例化的问题,但找不到合适的方法或者至少找不到解决方法.每次数据库迁移都已更新,并通过dnvm ef迁移应用于数据库.谢谢你的帮助!

Jka*_*kal 7

没关系,我设法解决了它!首先,我制作了GET Edit异步任务来跟踪工作流程

// GET: Edit
    [HttpGet]
    public async Task<IActionResult> Edit(Guid? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(404);
        }

        ApplicationUser userforEdit = await _userManager.FindByIdAsync(id.ToString());

        if (userforEdit == null)
        {
            return new HttpStatusCodeResult(404);
        }

        return View(userforEdit);
    }
Run Code Online (Sandbox Code Playgroud)

然后我创建了一个新的ApplicationUser并手动传递了这些字段:

// POST: Edit
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Edit(ApplicationUser editedUser)
    {
        if (ModelState.IsValid)
        {
            ApplicationUser userforEdit = await _userManager.FindByIdAsync(editedUser.Id.ToString());

            userforEdit.UserFirstName = editedUser.UserFirstName;
            userforEdit.UserLastName = editedUser.UserLastName;
            userforEdit.UserName = editedUser.UserName;
            userforEdit.Email = editedUser.Email;

            var UpdateUserResult = await _userManager.UpdateAsync(userforEdit);

            return RedirectToAction("Index");
        }
        return View(editedUser);
    }
Run Code Online (Sandbox Code Playgroud)

我发布它以防其他人卡在那里!如果还有另一种更优雅或更安全的方式,请告诉我们.