Aaron. S
Aaron. S

Reputation: 527

ASP.Net & EF Core 2 and Concurrency token error

Entity Framework Core 2, added a concurrency token property to model

[Timestamp]
public byte[] Timestamp { get; set; }

Controller Edit fails

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Edit(Guid id, [Bind("Id,Name,Description,IsDeleted,ParentId")] ItemStatus itemStatus)
        {
            if (id != itemStatus.Id)
                return NotFound();

            if (ModelState.IsValid)
            {
                try
                {
                    _context.Update(itemStatus);
                    await _context.SaveChangesAsync();
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!ItemStatusExists(itemStatus.Id))
                    {
                        return NotFound();
                    }
                    else
                    {
                        throw;
                    }
                }
                return RedirectToAction(nameof(Index));
            }

            ViewData["ParentId"] = new SelectList(_context.ItemStatus, "Id", "Description", itemStatus.ParentId);
            return View(itemStatus);
        }

the specific error I am receiving occurs when SaveChangesAsync occurs. catch pops and when I step in it goes straight to the throw.

DbUpdateConcurrencyException: Database operation expected to affect 1 row(s) but actually affected 0 row(s). Data may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=527962 for information on understanding and handling optimistic concurrency exceptions.

Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.ThrowAggregateUpdateConcurrencyException(int commandIndex, int expectedRowsAffected, int rowsAffected)

searching for the error message doesn't help. did find this article but it appears to be no help.

https://learn.microsoft.com/en-us/ef/core/saving/concurrency

Upvotes: 2

Views: 2799

Answers (1)

Aaron. S
Aaron. S

Reputation: 527

as indicated in the comments, I was missing a hidden field to 'save' the timestamp in the view.

Followed this example: https://learn.microsoft.com/en-us/aspnet/core/data/ef-mvc/concurrency

for clarity added my altered Edit. I had to do something similar to Delete too. this needs to be added to the Edit view <input type="hidden" asp-for="Timestamp" />

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Edit(Guid id, [Bind("Id,Name,Description,ParentId,Timestamp")] ItemStatus itemStatus)
        {
            if (id != itemStatus.Id)
                return NotFound();

            if (ModelState.IsValid)
            {
                try
                {
                    _context.Update(itemStatus);
                    await _context.SaveChangesAsync();
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!ItemStatusExists(itemStatus.Id))
                    {
                        return NotFound();
                    }
                    else
                    {
                        throw;
                    }
                }
                return RedirectToAction(nameof(Index));
            }

            ViewData["ParentId"] = new SelectList(_context.ItemStatus, "Id", "Description", itemStatus.ParentId);
            return View(itemStatus);
        }

Upvotes: 2

Related Questions