I have a situation where my DTOs require DateTime
properties but my POCOs use nullable datetimes. To avoid having to create ForMember
mappings for every property with this condition I created an ITypeConverter<DateTime?, DateTime>
. The problem I ran into is when both DTO and POCO have nullable DateTimes this converter is called. The DestinationType
is DateTime
even though the property is a nullable datetime. Any idea how I would make this converter run only for actual nullable datetimes?
public class FooDTO
{
public DateTime? FooDate { get; set; }
}
public class FooPoco
{
public DateTime? FooDate { get; set; }
}
class Program
{
static void Main(string[] args)
{
Mapper.CreateMap<FooDTO, FooPoco>();
Mapper.CreateMap<DateTime?, DateTime>()
.ConvertUsing<NullableDateTimeConverter>();
var poco = new FooPoco();
Mapper.Map(new FooDTO() { FooDate = null }, poco);
if (poco.FooDate.HasValue)
Console.WriteLine(
"This should be null : {0}",
poco.FooDate.Value.ToString()); //Value is always set
else
Console.WriteLine("Mapping worked");
}
}
public class NullableDateTimeConverter : ITypeConverter<DateTime?, DateTime>
{
// Since both are nullable date times and this handles converting
// nullable to datetime I would not expect this to be called.
public DateTime Convert(ResolutionContext context)
{
var sourceDate = context.SourceValue as DateTime?;
if (sourceDate.HasValue)
return sourceDate.Value;
else
return default(DateTime);
}
}
I found this post AutoMapper TypeConverter mapping nullable type to not-nullable type but it was little help.
Without looking I suspect its calling your TypeCoverter
because its the best match for the types being converted.
If you create another TypeConverter
with the correct types it should work fine. Eg:
public class DateTimeConverter : ITypeConverter<DateTime?, DateTime>
{
public DateTime Convert(ResolutionContext context)
{
var sourceDate = context.SourceValue as DateTime?;
if (sourceDate.HasValue)
return sourceDate.Value;
else
return default(DateTime);
}
}
public class NullableDateTimeConverter : ITypeConverter<DateTime?, DateTime?>
{
public DateTime? Convert(ResolutionContext context)
{
var sourceDate = context.SourceValue as DateTime?;
if (sourceDate.HasValue)
return sourceDate.Value;
else
return default(DateTime?);
}
}
Note that if you wish these can be further simplified to
public class DateTimeConverter : TypeConverter<DateTime?, DateTime>
{
protected override DateTime ConvertCore(DateTime? source)
{
if (source.HasValue)
return source.Value;
else
return default(DateTime);
}
}
public class NullableDateTimeConverter : TypeConverter<DateTime?, DateTime?>
{
protected override DateTime? ConvertCore(DateTime? source)
{
return source;
}
}
Then just initialise both converters:
Mapper.CreateMap<DateTime?, DateTime>().ConvertUsing<DateTimeConverter>();
Mapper.CreateMap<DateTime?, DateTime?>().ConvertUsing<NullableDateTimeConverter>();
Mapper.AssertConfigurationIsValid();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With