Cannot update record in entity framework

197 Views Asked by At

The error message I get is this : DbUpdateConcurrencyException

I am using updating the IdentityRole table. I am using a ViewModel to display and capture data, then passing it back in, in my OnPost(). The data comes into my IdentityRole property as expected. I made sure the primary key is hidden in the form. I have also tried _context.Update(Role) in combination with SaveChanges() and i always get the same error. I also ensured i have the [BindProperty] on both my ViewModel and my IdentityRole properties.

Here is my Controller or code behind.

    public IActionResult OnPost()
    {
        Role.Name = RoleViewModel.RoleName;
        Role.NormalizedName = RoleViewModel.RoleName.ToUpper();
        Role.ConcurrencyStamp = DateTime.Now.ToString();

        if (!ModelState.IsValid)
        {
            return Page();
        }

        _context.Entry(Role).Property(x => x.Name).IsModified = true;
        _context.Entry(Role).Property(x => x.NormalizedName).IsModified = true;
        _context.Entry(Role).Property(x => x.ConcurrencyStamp).IsModified = true;

        _context.SaveChanges();
        return Redirect("/Admin/HomeRole");
    }

My ViewModel

public class EditRoleViewModel
{
    public EditRoleViewModel()
    {
        Users = new List<string>();
    }

    public string Id { get; set; }

    [Required(ErrorMessage = "Role Name is required")]
    public string RoleName { get; set; }

    public List<string> Users { get; set; }
}

Here is the form

    <form method="post" class="mt-3">
        <input asp-for="RoleViewModel.Id" type="hidden" />
        <input asp-for="RoleViewModel.Users" type="hidden" />
        <div class="form-group row">
            <label asp-for="RoleViewModel.RoleName" class="col-sm-2 col-form-label"></label>
            <div class="col-sm-10">
                <input asp-for="RoleViewModel.RoleName" class="form-control">
                <span asp-validation-for="RoleViewModel.RoleName" class="text-danger"></span>
            </div>
        </div>
</form>
2

There are 2 best solutions below

1
Max Taylor-Hayden On BEST ANSWER

Here is the answer to my question

    public async Task<IActionResult> OnPost(EditRoleViewModel roleViewModel)
    {
        var role = await roleManager.FindByIdAsync(roleViewModel.Id);

        role.Name = roleViewModel.RoleName;

        var result = await roleManager.UpdateAsync(role);

        return Page();
    }
1
Swinkaran On

From what I see in your question, you need to pass the Id for Http Post. I understand that you are hiding the Id in the form but you need pass it to the controller and then to the Model to save. So, something like below,

public IActionResult OnPost(RoleViewModel model){......}

then assign the Id. If you are updating the row with no Id, then you will get this exception in DbContext.

For further reading in MSDN

Asp.Net controller snippets

Check these too. Try and let me know.