I'm using AutoMapper for mapping between my DTOs and business objects. This works fine.
However, I have a Web API which accepts PUT requests in order to update entities. The action looks like this:
public virtual async Task<IHttpActionResult> Put(string id, [FromBody] ProjectDto projectDto)
When mapping from ProjectDto to Project (business object), it maps all values from ProjectDto. Let's say I want to update a project's name, by sending the following JSON to the API:
{
"projectId": 10,
"name": "The new name"
}
Since I haven't given a value for all of the other properties of ProjectDto, AutoMapper will map default values where I haven't supplied a value.
For example, if ProjectDto had a couple of extra fields, they would now be null:
{
"projectId": 10,
"name": "The new name",
"createdDate": null,
"manager": null
}
..etc.
My mapping looks like this:
cfg.CreateMap<ProjecDto, Project>()
.ForAllMembers(opt => opt.Condition(x => x != null));
.. but AutoMapper is still mapping null values.
I have looked at this question, but I just get "ProjectDto does not contain a definition for IsSourceValueNull" when I try to copy their solution.
The Web API controller action (it's generic, TDto is an empty marker interface. T and TDto resolves at runtime to Project and ProjectDto, respectively.):
public virtual async Task<IHttpActionResult> Put(string id, [FromBody] TDto model)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
var entity = _dataContext.GetRepository<T>().GetById(id);
if (entity == null)
return NotFound();
var entityToUpdate = _mapper.Map<T>(model);
var updatedEntity = _dataContext.GetRepository<T>().Update(entity);
var updatedEntityDto = _mapper.Map<TDto>(updatedEntity);
return Ok(updatedEntityDto);
}