Using AutoMapper in Your ASP.Net MVC Applications

In this article I will explain the AutoMapper component and how to use it in an Asp.Net MVC application with few source code samples.

About AutoMapper

AutoMapper is an external component that helps in creating a mapping between a source and  destination model types. Once the mapping is created then the source model object can be converted to a destination model object with ease and with less cluttered code. The developers can get rid of the explicit conversions as implemented in the following code.

public Car ConvertAutomobileToCar(Automobile automobile)
{
    return new Car()
    {
        RegistrationNumber = automobile.RegistrationNumber,
        Color = automobile.Color,
        Model = automobile.Model
    };
}

If the classes in the above example have numerous properties and if there are many more such object mapping needed to be done then it becomes a tedious job for the developer as well as making the code sloppy and prone to coding errors.

AutoMapper works on a convention based mechanism, which means that the conventions specified by the AutoMapper component need to be followed to get it working. The component can be imported to the application through NuGet packages and more information can be found at AutoMapper.org.

Fig 1.0 shows the AutoMapper components added in the project references after the NuGet package import was done.

AutoMapper components
Fig 1.0 – AutoMapper components

AutoMapper in Asp.Net MVC Applications

In Asp.Net MVC applications, strictly a View can be bound to only one Model, the View requires bit more massaged data than the domain model object and also the properties required for the Views don’t exactly match with the domain models. Due to these facts in Asp.Net MVC, the domain (or business) models need to be converted to the View models before sending them across to the Views. This is where the AutoMapper component gets its place in Asp.Net MVC applications, as the object conversion will be required for almost all of the Views.

The conversion using the AutoMapper works in two steps:

1. Create a mapping between the Source and Destination model types. This should be done at the application level and the best place would be the Global.asax page.

2. Call the Map method wherever the conversion is required.

Mapping Features and Code Samples

In this section I will take you through a few important features that the AutoMapper component exhibits, along with samples in an Asp.Net MVC application. As a first step create an empty Asp.Net MVC 4 application and name it LearnAutoMapper. Then add the following models to the MVC application, where Automobile is the domain model and Car is the View model.

public class AutomobileDM
{
    public string AutoMobileType { get; set; }
    public string RegistrationNumber { get; set; }
    public string Color { get; set; }
    public string Model { get; set; }
    public double Price { get; set; }
    public double Tax { get; set; }
}
public class CarVM
{
    public string RegistrationNumber { get; set; }
    public string Color { get; set; }
    public string Model { get; set; }
}

Add the CarController with the Default index action method. Now add the View named GetCar strongly typed to the CarVM model and also add the corresponding ActionMethod GetCar. The GetCar method accepts a POST request from Index view with registrationNumber as the parameter and returns back the GetCar view displaying the details of the Car.

Flattening

This is a straight one to one mapping between the objects and the mapping is made through the property names. AutoMapper expects the property names to be the same between the ViewModel and DomainModel.

In the GetCar action method let us use AutoMapper to convert the AutomobileDM to CarDM. The source code example is provided below.

[HttpPost]
public ActionResult GetCar(string registrationNumber)
{
    AutomobileDM automobile = DataAccess.GetAutomobileFromDatabase(registrationNumber);
 
    //Create the mapping between AutomobileDM to CarVM
    Mapper.CreateMap<AutomobileDM, CarVM>();
 
    //Perform the conversion and fetch the destination view model
    CarVM car = Mapper.Map<CarVM>(automobile);
 
    return View("GetCar", car);
}

Projection Feature

Projection is the feature where you want to create custom mapping between the properties where the property name doesn’t match or it is not a one to one mapping. In our automobile example let us move to the next step by adding the following property to the CarVM model.

public double TotalPurchasePrice { get; set; }

While converting from Automobile this property should be populated by the summation of the AutomobileDM properties Price and Tax. Following is the sample GetCar code highlighting the projection feature.

[HttpPost]
public ActionResult GetCar(string registrationNumber)
{
    AutomobileDM automobile = DataAccess.GetAutomobileFromDatabase(registrationNumber);
 
    //Create the mapping between AutomobileDM to CarVM
    Mapper.CreateMap<AutomobileDM, CarVM>()
        .ForMember(dest => dest.TotalPurchasePrice, opt => opt.MapFrom(src => src.Price + src.Tax));
 
    //Perform the conversion and fetch the destination view model
    CarVM car = Mapper.Map<CarVM>(automobile);
 
    return View("GetCar", car);
}

Nested Models

What if the models are nested? This feature of AutoMapper is to do just that. Let us take our example to the next level by making the domain and view model nested.

Create class InvoiceVM and add a property to CarVM with type InvoiceVM.

public class InvoiceVM
{
    public int InvoiceId { get; set; }
    public string Text { get; set; }
}
public InvoiceVM Invoice { get; set; }

Create class InvoiceDM and add a property to AutomobileDM with type InvoiceDM.

public class InvoiceDM
{
    public int InvoiceId { get; set; }
    public string Text { get; set; }
}
public InvoiceDM Invoice { get; set; }

Now let us go and modify the mapping in the GetCar method. Following is the sample code.

[HttpPost]
public ActionResult GetCar(string registrationNumber)
{
    AutomobileDM automobile = DataAccess.GetAutomobileFromDatabase(registrationNumber);
 
    //Create the mapping between AutomobileDM to CarVM
    Mapper.CreateMap<AutomobileDM, CarVM>();
    //As a next step define the mapping for the nested Invoice objects
    Mapper.CreateMap<InvoiceDM, InvoiceVM>();
 
    //Perform the conversion and fetch the destination view model
    //Note that here there is no explicit mentioning of the Invoice objects
    CarVM car = Mapper.Map<CarVM>(automobile);
 
    return View("GetCar", car);
}

The important thing to note in all of the above examples is that only the CreateMapping call is getting altered and not the Map method calls. So the customization will be required to be done only once in your application and the conversion code will not require any changes to get these features implemented.

In addition to the above features there are many more, like type converters, value resolvers, Containers, inheritance in the mapping, etc. Happy reading!

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read