2

Closed

Mapping between Nullable types doesn't work

description

Using the latest DLL on Google Code (r79), I am still unable to map between two Nullable<double> types. Both ends of the mapping are Nullable<double>, yet I cannot map between them. Here's how my mapping is setup:
 
        Mapper.CreateMap<Foo, Bar>()
            .ForMember(b => b.Component.Minimum, opt => opt.MapFrom(f => f.Minimum));
 
Both Bar.Component.Minimum and Foo.Minimum are defined as Nullable<double>. When it tries to map them, this is the exception that is thrown:
 
Exception of type 'AutoMapper.AutoMapperMappingException' was thrown.
----> AutoMapper.AutoMapperMappingException : Trying to map System.Double to System.Nullable`1[[System.Double, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].
Using mapping configuration for Foo to Bar
Destination property: Minimum
Exception of type 'AutoMapper.AutoMapperMappingException' was thrown.
----> System.Reflection.TargetException : Object does not match target type.
at AutoMapper.MappingEngine.AutoMapper.IMappingEngineRunner.Map(ResolutionContext context)
at AutoMapper.MappingEngine.Map(Object source, Object destination, Type sourceType, Type destinationType)
at AutoMapper.MappingEngine.Map[TSource,TDestination](TSource source, TDestination destination)
at AutoMapper.Mapper.Map[TSource,TDestination](TSource source, TDestination destination)
Closed Jun 11, 2009 at 4:54 PM by jbogard
Fixed this one in R81. I changed how nullable mappers work, I was trying to be clever, rarely a good idea.

comments

jbogard wrote Jun 5, 2009 at 1:41 AM

Whoops. I'll take a look at this one, looks like I wound up breaking something with the fix for Bennage's issue with nullable types + custom type resolvers.

WaheedSayed wrote Jun 8, 2009 at 2:37 PM

I'm new to AutoMapper and I faced an issue with nullables but I'm not sure If this is the same issue here.
The point that I'm mapping a property of type DateTime to Nullable<DateTime> because it is in a nested type that may not be available.
like this:
Mapper.CreateMap<Customer, CustomerDTO>()
.ForMember(dest => dest.ActualCheckOutTime, opt => opt.MapFrom(src => src.CheckOutInfo.ActualCheckOutTime))
So if the customer did not check out there will be no CheckOutInfo this is why I used Nullable<DateTime>

I got the following exception:
Exception of type 'AutoMapper.AutoMapperMappingException' was thrown.
---> AutoMapper.AutoMapperMappingException: Trying to map Customer to CustomerDTO.
Using mapping configuration for Diar.Core.Customer to Diar.Core.DataTrasferObjects.CustomerDTO
Exception of type 'AutoMapper.AutoMapperMappingException' was thrown.
---> AutoMapper.AutoMapperMappingException: Trying to map System.Object to System.Nullable`1[[System.DateTime, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].
Using mapping configuration for Customer to CustomerDTO
Destination property: ActualCheckOutTime

After a many hours I reached the following. I defined a type converter (from Object to DateTime?)
    Mapper.CreateMap<Object, DateTime?>().ConvertUsing<ObjectToDateTimeConverter>();

    public class ObjectToDateTimeConverter : ITypeConverter<Object, DateTime?>
    {
        public DateTime? Convert(object source)
        {
            DateTime result;
            bool isDateTime = false;

            if (source == null) return null;
            if (source.GetType() == typeof(DateTime)) return ((DateTime)source);
            if (source as String != null)
            {
                isDateTime = DateTime.TryParse((string)source, out result);
                if (isDateTime) return result;
            }

            throw new InvalidCastException("Can not convert to Nullable DateTime");
        }
    }
Then, the exception disappeared & tests started to work fine.
Kindly, I'd like to let me know if this is same issue & If I should remove this code after fixing this issue.

jbogard wrote Jun 8, 2009 at 4:32 PM

@Waheed

It's the same issue, because the nullable-type mapper uses the source type for matching, instead of the destination type. For custom-mapped members, it doesn't know what the source type would be for nulls.