Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# InvalidOperationException:无法跟踪实体类型“ApplicationUser”的实例_C#_Asp.net Core - Fatal编程技术网

C# InvalidOperationException:无法跟踪实体类型“ApplicationUser”的实例

C# InvalidOperationException:无法跟踪实体类型“ApplicationUser”的实例,c#,asp.net-core,C#,Asp.net Core,完整错误消息: InvalidOperationException:无法跟踪实体类型“ApplicationUser”的实例,因为已在跟踪另一个具有{Id}相同键值的实例。附着现有实体时,请确保仅附着一个具有给定键值的实体实例。考虑使用“dBraveTopStudioBuffel.EnabelSythViDeAtCug”来查看冲突的键值。 当我尝试更新查看页面上的用户信息时,我遇到此错误 更新代码: [HttpGet] public ActionResult Edit(string

完整错误消息:

InvalidOperationException:无法跟踪实体类型“ApplicationUser”的实例,因为已在跟踪另一个具有{Id}相同键值的实例。附着现有实体时,请确保仅附着一个具有给定键值的实体实例。考虑使用“dBraveTopStudioBuffel.EnabelSythViDeAtCug”来查看冲突的键值。

当我尝试更新查看页面上的用户信息时,我遇到此错误

更新代码:

  [HttpGet]
    public ActionResult Edit(string id)
    {
        //Get user and return the Edit View
        ApplicationViewModel model = db.Users.Where(u => u.Id == id)
      .Select(u => new ApplicationViewModel()
      {             
          UserName = u.UserName,
          ClearTextPassword = u.ClearTextPassword,            
          PhoneNumber = u.PhoneNumber,             
          Enabled = u.Enabled

            // Add the remainder properties
        }).FirstOrDefault();
        return View(model);
    }


    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Edit(string id, ApplicationViewModel model)
    {
        if (ModelState.IsValid)
            return View(model);

        var user = await _userManager.FindByIdAsync(id);
        if (user == null)
            return NotFound();

        user.UserName = model.UserName;
        user.ClearTextPassword = model.ClearTextPassword;
        user.Enabled = model.Enabled;
        user.PhoneNumber = model.PhoneNumber;

        {
            var result = await _userManager.UpdateAsync(user);
            if (result.Succeeded)
            {
                //db.Entry(listdata).State = EntityState.Modified;
                //db.SaveChanges();
                return RedirectToAction("Index");
            }
        }
        return View(user);
    }

我希望用户信息保存到数据库中,并在单击“保存”按钮后在主页上显示更改。

这就是为什么您应该使用视图模型。除了这一个特殊的例外,实际上还有其他原因

首先,解释发生了什么。在代码库中的某个地方,在处理此请求的过程中,查询了与您试图编辑的内容具有相同id的ApplicationUser实例。这可能是由许多不同的事情造成的:重要的是,您的上下文已经在跟踪这个特定的实例

当您在操作中将post直接绑定到ApplicationUser时,您正在创建一个完全不同的实例。将该新实例直接添加到您的上下文中,也会尝试开始跟踪该实例,但由于与您的上下文已经跟踪的内容存在冲突而失败

两个要点:

编辑实体时,总是将其从数据库中重新提取,根据需要对其进行更改,然后将该实例保存回数据库

您不应直接将从post创建的任何内容(即此处操作的用户参数)保存到数据库中。您不应该这样做的原因有很多,但安全是首要的。Post数据是来自用户的数据,从不信任用户

使用视图模型可以解决这两个问题。您只需创建一个类,如ApplicationUserModel(名称无关紧要),然后仅为您希望允许用户修改的数据添加属性。换言之,您将排除诸如ID之类的内容,ID应该始终来自URL、创建日期和其他审计跟踪信息等。然后,将帖子绑定到此视图模型,从数据库中提取要修改的实际实体,将相关数据映射到该实体上,然后保存该实体

总之,这将使您的操作看起来像:

[HttpPost("{id}"]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(string id, ApplicationUserViewModel model)
{            
    if (!ModelState.IsValid)
        return View(model);

    var user = await _userManager.FindByIdAsync(id);
    if (user == null)
        return NotFound();

    user.FirstName = model.FirstName;
    user.LastName = model.LastName;
    // etc. You can also use a mapping library like AutoMapper instead

    var result = await _userManager.UpdateAsync(user);
    if (result.Succeeded)
    {
        // db.Entry(listdata).State = EntityState.Modified;
        // db.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(model);
}

我认为这将工作,但我失去了我的编辑链接url。它以前是localhost/editprofile/Edit。现在是localhost/{id},链接中断。我需要做什么才能恢复链接?你一定使用了基于约定的路由。默认路由将接受一个id,因此您可能只需将属性更改回[HttpPost]。要坚持使用基于属性的路由,只需将类似[Route[controller]]的内容应用于控制器类,然后应用[HttpPostedit/{id}]。现在我收到一个错误“InvalidOperationException:传递到ViewDataDictionary的模型项的类型为“FE.Models.ApplicationViewModel”,但此ViewDataDictionary实例需要“FE.Models.ApplicationUser”类型的模型项。我正在使用HttpGet上的ApplicationUser执行编辑操作。更新了OP中的代码。视图模型也是您的视图需要使用的。我得到的错误与get而不是post上发生的错误相同。这就是我将视图更改为@model FE.Models.ApplicationViewModel的内容。httpget中的所有内容都需要更改为ApplicationViewModel吗?我看不出这段代码与答案中的代码有什么区别。如果你改变了它,其他人看到原来的错误版本是有意义的,而不是固定版本。