public async Task <IActionResult> Get(int id, [FromQuery] bool forUpdate = false) { if (id < 1) { return(new NotFoundResult()); } if (forUpdate) { var unitOfWork = _serviceProvider.GetService <IUnitOfWork <Contact> >(); HttpContext.Response.RegisterForDispose(unitOfWork); var result = await unitOfWork.Repo.LoadAsync(id, User, true); // return version for tracking on client. It is not // part of the C# class so it is tracked as a "shadow property" var concurrencyResult = new ContactConcurrencyResolver { OriginalContact = result, RowVersion = result == null ? null : await unitOfWork.Repo.GetPropertyValueAsync <byte[]>( result, ContactContext.RowVersion) }; return(new OkObjectResult(concurrencyResult)); } else { var result = await _repo.LoadAsync(id, User); return(result == null ? (IActionResult) new NotFoundResult() : new OkObjectResult(result)); } }
public async Task <IActionResult> PutAsync(int id, [FromBody] ContactConcurrencyResolver value) { // I got nothing if (value == null || value.OriginalContact == null || value.OriginalContact.Id != id) { return(new BadRequestResult()); } if (ModelState.IsValid) { var unitOfWork = _serviceProvider.GetService <IUnitOfWork <Contact> >(); HttpContext.Response.RegisterForDispose(unitOfWork); unitOfWork.SetUser(User); // this gets the contact on the board for EF Core unitOfWork.Repo.Attach(value.OriginalContact); await unitOfWork.Repo.SetOriginalValueForConcurrencyAsync( value.OriginalContact, ContactContext.RowVersion, value.RowVersion); try { await unitOfWork.CommitAsync(); return(new OkResult()); } catch (RepoConcurrencyException <Contact> dbex) { // oops it has been updated, so send back the database version // and the new RowVersion in case the user wants to override value.DatabaseContact = dbex.DbEntity; value.RowVersion = dbex.RowVersion; return(new ConflictObjectResult(value)); } } else { return(new BadRequestObjectResult(ModelState)); } }