I recently came across a blog post on LosTechies detailing how AutoMapper could be used to map from models to ViewModels in MVC controllers utilising custom ActionFilters.

I found this to be a fantastic way of keeping the code in our controller actions concise, avoiding 'fat controllers'. In essence it allows you to decorate an MVC action with the [AutoMap(typeof(Person),typeof(PersonViewModel))] and then instead of having to write any mapping code at all within the action it will automatically take the model supplied within the return View(); statement and map it to the defined ViewModel.

One limitation I found was that if I wanted to create a View that was strongly typed to a List<MyViewModel> however, this action filter wouldn't work and I'd have to result to manually writing the code to map the objects in the controller action.

Based on the code written by Jimmy Bogard in the above post I have extended it to map lists of view models as well as single instances of a view model.

A custom ActionFilter was defined (inheriting from ActionFilterAttribute) and within the constructor the source and destinations types are passed in.

I then have the check if this model is a simple model object or whether it is a List of Models. As this need to remain generic I won't know at compile time what List<> type it will be. Therefore this is how I need to check if it's a list:

if (model is IList && model.GetType().IsGenericType)

The mapping for a simple Model is simple and handled within the else statement with automapper by calling Mapper.DynamicMap(model,SourceType,DestType).

If however I'm dealing with a list of models I will first need to create a List of my desired type, which again we won't know at compile time. This can be achieved by utilising (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(DestType)).

I am then able to iterate over the original List of Objects and map each individually adding them to my new List of ViewModels.

The final step is to update the ViewModel within the context to the new List of ViewModels. This is what will be used by the ViewEngine.

The full code for the custom ActionFilter can be seen below and an example solution is available on my GitHub account here.