1

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?

2
  • HTTP 500 means a server-side exception. What is the exception? Commented Jan 11, 2018 at 19:36
  • 1
    Does SaveChangesAsync return a bool or an int Commented Jan 11, 2018 at 19:39

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Yes, of course. So in this situation should I somehow handle this more gracefully in my controller or should I prevent the request ever being made?
@TDC that is totally up to you. if there are no changes to send to the server then save the trip. You could also not throw an exception and provided a model state message back to the client.
I think I will evaluate the object before sending the request for equality. Thanks for the prompt and concise answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.