Question

I've been messing with AutoMapper for a few days now, but I am having the most difficult time mapping values for what to me seems like basic tasks. I'm most likely the dumb one, but it's starting to get really frustrating with all these constant exceptions being thrown. /rant

Anyway, I have an Entity Framework proxy object Company. Through a base class Entity it has a property called CreatedDateTime which is a DateTime. I also have a DTO object called CompanyDto, which has a property called CreatedDateTime which is a string. All I want to do is take the DateTime value and flatten it to ToString("g"). I've tried a bunch of things, all of which throw an exception of some kind. The only mapping that has worked is, surprise, surprise: .Ignore(). Here's my latest attempt with a TypeConverter:

Mapper.CreateMap<DateTime, string>().ConvertUsing<DateTimeToStringConverter>();

public sealed class DateTimeToStringConverter : TypeConverter<DateTime, string> {
    protected override string ConvertCore(
        DateTime source) {
        if (source != null) {
            return source.ToString("g");
        }

        return string.Empty;
    }
}

And that causes this: Type 'System.String' does not have a default constructor

Jimmy, you browsing SO? Point me in the right direction please because at this point I think I'll get more work done by manually mapping than with AutoMapper.

Oh, this is with AutoMapper 3.1.1, Entity Framework 6.1, ASP.NET MVC 5.1.1 for those who wonder.

Was it helpful?

Solution

Try this instead of the custom converters..

Mapper.CreateMap<Company, CompanyDto>()
      .ForMember(d => d.CreatedDateTime,
        expression => expression.ResolveUsing(s=>s.CreatedDateTime.ToString("g")));

// now do the Mapper.Map from Company to CompanyDto.

OTHER TIPS

You can also simply use the MapFrom method instead of the ResolveUsing

public class EFObject
{
    public DateTime D { get; set; }
}
public class DTOObject
{
    public string DS { get; set; }
}

internal class Program
{
    private static void Main(string[] args)
    {
        Mapper.CreateMap<EFObject, DTOObject>().
            ForMember(dtoo => dtoo.DS, opt => opt.MapFrom(efo => efo.D.ToString("g")));

        var fromDB = new EFObject() { D = DateTime.Now };
        var toDTO = Mapper.Map<EFObject, DTOObject>(fromDB);
    }
}

I'd recommend using MapFrom instead of ResolveUsing since MapFrom adds some null checking along the resolution path (among other things). Here is a good discussion about the subject

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top