更新用户商店标识框架3.0

问题描述 投票:1回答:2

我几天来一直在寻找解决方案,只找到与旧版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; }
}

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);
    }

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

@Html.ActionLink("Edit", "Edit", new { id = item.Id })

以及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);
    }
}

}

执行期间出现错误异常

var UpdateUserResult = await _userManager.UpdateAsync(editedUser);

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

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

c# asp.net-mvc entity-framework asp.net-identity
2个回答
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);
    }

然后我创建了一个新的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);
    }

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


0
投票

做同样事情的更好方法:

 ApplicationUser userToEdit = await _userManager.FindByIdAsync(applicationUser.Id.ToString());

 foreach (System.Reflection.PropertyInfo property in typeof(ApplicationUser).GetProperties()) {
                property.SetValue(userToEdit, property.GetValue(applicationUser));
 }

代替 :

 ApplicationUser userforEdit = await _userManager.FindByIdAsync(editedUser.Id.ToString());

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

(userToEdit = userforEdit&applicationUser = editedUser)

© www.soinside.com 2019 - 2024. All rights reserved.