Can Automapper map a paged list?

Viewed 9854

I'd like to map a paged list of business objects to a paged list of view model objects using something like this:

var listViewModel = _mappingEngine.Map<IPagedList<RequestForQuote>, IPagedList<RequestForQuoteViewModel>>(requestForQuotes);

The paged list implementation is similar to Rob Conery's implementation here: http://blog.wekeroad.com/2007/12/10/aspnet-mvc-pagedlistt/

How can you setup Automapper to do this?

7 Answers

AutoMapper does not support this out of the box, as it doesn't know about any implementation of IPagedList<>. You do however have a couple of options:

  1. Write a custom IObjectMapper, using the existing Array/EnumerableMappers as a guide. This is the way I would go personally.

  2. Write a custom TypeConverter, using:

    Mapper
        .CreateMap<IPagedList<Foo>, IPagedList<Bar>>()
        .ConvertUsing<MyCustomTypeConverter>();
    

    and inside use Mapper.Map to map each element of the list.

If you're using Troy Goode's PageList, there's a StaticPagedList class that can help you map.

// get your original paged list
IPagedList<Foo> pagedFoos = _repository.GetFoos(pageNumber, pageSize);
// map to IEnumerable
IEnumerable<Bar> bars = Mapper.Map<IEnumerable<Bar>>(pagedFoos);
// create an instance of StaticPagedList with the mapped IEnumerable and original IPagedList metadata
IPagedList<Bar> pagedBars = new StaticPagedList<Bar>(bars, pagedFoos.GetMetaData());

AutoMapper automatically handles conversions between several types of lists and arrays: http://automapper.codeplex.com/wikipage?title=Lists%20and%20Arrays

It doesn't appear to automatically convert custom types of lists inherited from IList, but a work around could be:

    var pagedListOfRequestForQuote = new PagedList<RequestForQuoteViewModel>(
        AutoMapper.Mapper.Map<List<RequestForQuote>, List<RequestForQuoteViewModel>>(((List<RequestForQuote>)requestForQuotes),
        page ?? 1,
        pageSize

It is easy with Automapper .net core 8.1.1

You just need to add type map to your mapperProfile and mapping the object inside pagedList

CreateMap(typeof(IPagedList<>), typeof(IPagedList<>));
CreateMap<RequestForQuote, RequestForQuoteViewModel>().ReverseMap();

It also can be and abstract class like PagedList. It is not related with class/ınterface type

And you can use it directly in mapper.Map - Initialize mapper from IMapper in the class constructor

RequestForQuote result
_mapper.Map<IPagedList<RequestForQuoteViewModel>>(result);
Related