Reputation: 3844
Suppose this Enum contract :
[DataContract]
public enum ReportType_DTO
{
[EnumMember]
Voice,
[EnumMember]
Text,
[EnumMember]
File
}
which have three members from 0 to 2 in the other side I have another Enum which have 7 member as:
public enum RptType
{
Word = 0,
Dynamic = 1,
Basic = 2,
StructuredReport = 3,
Word2007 = 4,
PDF = 5,
WebReport = 6,
WebTemplate = 7
}
so I configure mapping as:
var mapper1 = new MapperConfiguration((cfg) =>
cfg.CreateMap<Report_C, Report_DTO>().AfterMap((reportC, reportDTO) =>
{
switch ((RptType)reportC.Type)
{
case RptType.Dynamic:
case RptType.PDF:
case RptType.Word:
case RptType.Word2007:
case RptType.WebTemplate:
reportDTO.Type = ReportType_DTO.File;
break;
case RptType.StructuredReport:
reportDTO.Type = ReportType_DTO.Voice;
break;
case RptType.Basic:
case RptType.WebReport:
reportDTO.Type = ReportType_DTO.Text;
break;
}
reportDTO.ReportUID = reportC.SOPInstanceUID;
}))
.CreateMapper();
and map the collection one by one:
var foundReports = pacsReports.Collection.Select(r => mapper1.Map<Report_DTO>(r)).ToList();
case RptType.StructuredReport
happened for one of collections member but when I checked the collection it seem that prop doesn't get new value as picture below:
this is clear in client-side we ending up with exception like :
Enum value '3' is invalid for type 'xxx.ReportType_DTO' and cannot be serialized. Ensure that the necessary enum values are present and are marked with EnumMemberAttribute attribute if the type has DataContractAttribute attribute.
is there another ways to force Automapper change the value explicitly?
UPDATE1:
Report_DTO
is a struct type but Report_C
is a class, can it be the reason (something like call by reference or call by value for struct
in mapping) ?
UPDATE2:
Yes struct
is the reason, by changing struct to class it work well, but I am returning DTO_OUT
as struct for some reason to force operation don't return null so I can't change them to class, I believe there must be a solution to tell autommaper call by reference, I think AfterMape
is a void method which change entered param in call by reference mechanism.
any idea and help would be appreciated.
Upvotes: 2
Views: 604
Reputation: 205589
There is no way to let AutoMapper pass struct
by reference to AfterMap
action. So you need a different approach, not based on AfterMap
.
One way is to create mapping from RptType
to ReportType_DTO
wrapping the switch logic in ConvertUsing
. Then create a mapping from Report_C
to Report_DTO
with typical ForMember
setup:
var mapper1 = new MapperConfiguration(cfg =>
{
cfg.CreateMap<RptType, ReportType_DTO>().ConvertUsing(rptType =>
{
switch (rptType)
{
case RptType.StructuredReport:
return ReportType_DTO.Voice;
case RptType.Basic:
case RptType.WebReport:
return ReportType_DTO.Text;
default:
return ReportType_DTO.File;
}
});
cfg.CreateMap<Report_C, Report_DTO>()
.ForMember(reportDTO => reportDTO.Type, opt => opt.MapFrom(reportC => (RptType)reportC.Type))
.ForMember(reportDTO => reportDTO.ReportUID, opt => opt.MapFrom(reportC => reportC.SOPInstanceUID));
})
.CreateMapper();
Upvotes: 3