Reputation: 1929
My Web Api Controller has an UpdateArea
method which is passed an id
and the updated values in the body. It is written as follows:
[HttpPut("{id}")]
public async Task<IActionResult> UpdateArea(Guid id, [FromBody] AreaForUpdateDto areaForUpdateDto)
{
// Check that the 'area' object parameter can be de-serialised to a AreaForUpdateDto.
if (areaForUpdateDto == null)
{
_logger.LogError("AreasController.UpdateArea failed: Could not map area object parameter to a AreaForUpdateDto");
// Return an error 400.
return BadRequest();
}
// Ensure that the Area exists.
var areaEntityFromRepo = _areaRepository.GetArea(id);
// Map(source object (Dto), destination object (Entity))
Mapper.Map(areaForUpdateDto, areaEntityFromRepo);
_areaRepository.UpdateArea(areaEntityFromRepo);
// Save the updated Area entity, added to the DbContext, to the SQL database.
if (await _areaRepository.SaveChangesAsync())
{
var areaFromRepo = _areaRepository.GetArea(id);
if (areaFromRepo == null)
return NotFound();
var area = Mapper.Map<AreaDto>(areaFromRepo);
return Ok(area);
}
// The save has failed.
_logger.LogWarning($"Updating Area {id} failed on save.");
throw new Exception($"Updating Area {id} failed on save.");
}
This works fine until my application calls for an update, but the body of the request is identical to the existing data in the database. When this happens the _areaRepository.SaveChangesAsync()
fails returning an error 500
.
This happens if the user opens an Edit Details dialog, does not change anything and then clicks the Edit button sending the request.
I could validate on the client, which is fine, but I was surprised that this caused an error.
Can anybody please explain why this is failing and where I should correct this?
Upvotes: 1
Views: 1158
Reputation: 247018
According to the logic explained by you
This happens if the user opens an Edit Details dialog, does not change anything and then clicks the Edit button sending the request.
and this snippet of code
//...code removed for brevity
// Save the updated Area entity, added to the DbContext, to the SQL database.
if (await _areaRepository.SaveChangesAsync())
{
var areaFromRepo = _areaRepository.GetArea(id);
if (areaFromRepo == null)
return NotFound();
var area = Mapper.Map<AreaDto>(areaFromRepo);
return Ok(area);
}
// The save has failed.
_logger.LogWarning($"Updating Area {id} failed on save.");
throw new Exception($"Updating Area {id} failed on save.");
if no changes were made to the file and an update was attempted then no changes would be made to the DbContext
which means that _areaRepository.SaveChangesAsync()
would be false
and thus continue on to
// The save has failed.
_logger.LogWarning($"Updating Area {id} failed on save.");
throw new Exception($"Updating Area {id} failed on save.");
and BAM 500 error on the server.
I recommend debugging/stepping through the suspect code to confirm its behavior is as explained above and then rethink and refactor the update logic.
Upvotes: 2