Home > Software design >  Automapper 11, string to Uri no longer works
Automapper 11, string to Uri no longer works

Time:02-04

since upgrading to automapper 11 trying to map a string to an Uri no longer works

Entity

public sealed class Website
{
    public int Id { get; set; }
    public string Name {get; set; }
    public string BaseAddress { get; set; }
}

object I'm mapping to

public sealed class WebsiteDto
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Uri BaseAddress { get; set; }
}

mapping profile contains

CreateMap<Website, WebsiteDto>();

and how I'm calling it

_mapper.Map<List<WebsiteDto>>(listOfWebsiteEntities);

This was working fine before upgrading to 11, I think it might be a bug but before I raise it as an issue Automapper suggests raising a question here, am I missing something?

after downgrading to automapper 10.1.1 it works again. the upgrade guide doesn't seem to mention anything related to this

CodePudding user response:

The issue affects only relative uris and happens due to the next breaking change:

System.ComponentModel.TypeConverter is no longer supported It was removed for performance reasons. So it’s best not to use it anymore. But if you must, there is a sample in the test project.

You can bring it back by adding TypeConverterMapper to mappers:

var cfg = new MapperConfiguration(cfg => cfg.Internal().Mappers.Insert(0, new TypeConverterMapper()))

public class TypeConverterMapper : ObjectMapper<object, object>
{
    public override bool IsMatch(TypePair context)
    {
        return GetConverter(context.SourceType).CanConvertTo(context.DestinationType) ||
            GetConverter(context.DestinationType).CanConvertFrom(context.SourceType);
    }

    public override object Map(object source, object destination, Type sourceType, Type destinationType, ResolutionContext context)
    {
        var typeConverter = GetConverter(sourceType);
        return typeConverter.CanConvertTo(destinationType) ? typeConverter.ConvertTo(source, destinationType) : GetConverter(destinationType).ConvertFrom(source);
    }
    private TypeConverter GetConverter(Type type) => TypeDescriptor.GetConverter(type);
}

Or create a mapping from string to Uri which, I would say, is better option. Quick and dirty one simulating behaviour of previous one can look like this:

cfg.CreateMap<string, Uri>().ConvertUsing(s => (Uri)new UriTypeConverter().ConvertFrom(s));

Or just:

cfg.CreateMap<string, Uri>().ConvertUsing(s => new Uri(s, UriKind.RelativeOrAbsolute));

Related github issue

  •  Tags:  
  • Related