Use Case
Let's say that you're mapping data from a View Model to a Domain Model. The View Model only contains some of the items within your Domain Model, in order to POST and update partial views, rather than the entire view.
class ViewModel {
public Guid id { get; set; }
public string name { get; set; }
public string address { get; set;}
}
class DomainModel {
public Guid id { get; set; }
public string name { get; set; }
public string address { get; set; }
public string houseColor { get; set; }
public virtual Vehicle car { get; set; }
}
Currently, when ViewModel is mapped to DomainModel, name and address will be set properly, but houseColor and car will be overwritten with null.
I have attempted using the following mappings to no effect. After mapping the data, houseColor and car are unintentionally overwritten with null :
var map1 = new MapperConfiguration(
cfg =>cfg.CreateMap<ViewModel,DomainModel>()
.ForAllMembers(o =>o.Condition(src =>src != null))
);
var map2 = new MapperConfiguration(
cfg =>cfg.CreateMap<ViewModel,DomainModel>()
.ForMember(dest =>dest.houseColor, o =>o.Ignore() )
.ForMember(dest =>dest.car, o =>o.Ignore() )
);
var map3 = new MapperConfiguration(
cfg =>cfg.CreateMap<ViewModel,DomainModel>()
.ForMember(dest =>dest.houseColor, o =>o.UseDestinationValue() )
.ForMember(dest =>dest.car, o =>o.UseDestinationValue() )
);
var map4 = new MapperConfiguration(
cfg =>cfg.CreateMap<ViewModel,DomainModel>()
.ForAllMembers(opts => opts.Condition((src, dest, srcMember) => srcMember != null))
);
Controller
[HttpPost]
public PartialViewResult _Partial_View(ViewModel VM) {
var DomainModel = db.DomainModels.Find(VM.Id);
//calculations to update VM data.
//Creation of mappings as detailed above.
var mapper = mapName.CreateMapper();
DomainModel = mapper.Map<ViewModel,DomainModel>(VM);
db.SaveChanges();
return PartialView("PartialView.cshtml",VM);
}
Is there any way to prevent AutoMapper from overwriting Domain model values with null, when the equivalent source value is undeclared?
Alternatives
One may simply take the values from the Domain Model, store them in variables, and put them back into the Domain Model after mapping, but this would easily become difficult to maintain, and defeats the purpose of using a mapper.
Additional Notes
A Stack Overflow post has attempted to address this issue, but the post is from September 2014, and uses a long-outdated version of AutoMapper, rendering the answer ineffective. AutoMapper can't prevent null source values if not all source properties match and How to ignore null values for all source members during mapping in Automapper 6?