更新用户商店标识框架3.0

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了更新用户商店标识框架3.0相关的知识,希望对你有一定的参考价值。

我几天来一直在寻找解决方案,只找到与旧版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迁移应用于数据库。谢谢你的帮助!

答案

没关系,我设法解决了它!首先,我制作了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);
    }

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

另一答案

做同样事情的更好方法:

 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)

以上是关于更新用户商店标识框架3.0的主要内容,如果未能解决你的问题,请参考以下文章

用于从 cloudkit 检索单列的代码模式/片段

片段“F1”不能在这里传播,因为“节点”类型的对象永远不能是“商店”类型

Django REST框架--认证和权限

AOP框架Dora.Interception 3.0 [3]: 拦截器设计

使用 Jetpack Compose 提升 Play 商店的用户体验

从 AngularJS url 中删除片段标识符(# 符号)