How to use AutoMapper in ASP.NET Core
By FoxLearn 2/21/2025 7:03:13 AM 20
What is AutoMapper?
AutoMapper is a powerful library used for object-to-object mapping, enabling automatic conversion between objects, which is particularly helpful for mapping complex objects (like Data Transfer Objects, or DTOs) to domain models, and vice versa. It eliminates the need for repetitive property mapping and helps keep your code cleaner and easier to maintain.
Why Use AutoMapper?
- Reduces Code: Instead of manually mapping properties, AutoMapper takes care of property mapping automatically.
- Improves Maintainability: By centralizing the mapping configuration, you only need to modify the logic in one place when changes are required.
- Increases Productivity: AutoMapper speeds up development by reducing the amount of manual mapping code.
- Standardizes Mapping: It ensures consistent and error-free mappings between objects.
How to Use AutoMapper in ASP.NET Core?
Step 1. Install AutoMapper
First, install AutoMapper and its integration with Dependency Injection by running the following commands in the NuGet Package Manager or the Package Manager Console:
Install-Package AutoMapper Install-Package AutoMapper.Extensions.Microsoft.DependencyInjection
Step 2. Create Models and DTOs
Define the models (e.g., Product
) and the corresponding DTOs (e.g., ProductDTO
).
public class Product { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } public int Stock { get; set; } } public class ProductDTO { public string Name { get; set; } public decimal Price { get; set; } }
Step 3. Create an AutoMapper Profile
Define the mapping configuration between the Product
and ProductDTO
objects in a MappingProfile
class.
using AutoMapper; public class MappingProfile : Profile { public MappingProfile() { CreateMap<Product, ProductDTO>(); CreateMap<ProductDTO, Product>(); } }
Step 4. Register AutoMapper in Program.cs
Register AutoMapper in the ConfigureServices()
method to enable dependency injection and automatic mapping configuration.
using AutoMapper; public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddAutoMapper(typeof(Program)); // Register AutoMapper }
Step 5. Use AutoMapper in a Controller
Here's how AutoMapper can be used in a ProductController
to map between Product
and ProductDTO
objects.
[ApiController] [Route("api/[controller]")] public class ProductController : ControllerBase { private readonly IMapper _mapper; public ProductController(IMapper mapper) { _mapper = mapper; } [HttpPost] public IActionResult CreateProduct([FromBody] ProductDTO productDto) { var product = _mapper.Map<Product>(productDto); // Save the product entity to the database return Ok(product); } [HttpGet("{id}")] public IActionResult GetProduct(int id) { // Retrieve the product entity from the database var product = new Product { Id = id, Name = "Sample Product", Price = 100, Stock = 50 }; var productDto = _mapper.Map<ProductDTO>(product); return Ok(productDto); } }
Example Output
CreateProduct Request (Input: ProductDTO)
{ "Name": "Laptop", "Price": 999.99 }
CreateProduct Response (Output: Product)
{ "Id": 1, "Name": "Laptop", "Price": 999.99, "Stock": 50 }
GetProduct Request (GET /api/product/1)
{ "Id": 1, "Name": "Laptop", "Price": 999.99 }
Mapping with Custom Logic
Sometimes, you may need to apply custom logic during the mapping process.
For example, you might need to format a field or compute a value.
Define Models and DTOs
public class Customer { public string FirstName { get; set; } public string LastName { get; set; } public DateTime BirthDate { get; set; } } public class CustomerDTO { public string FullName { get; set; } public int Age { get; set; } }
Create a Mapping Profile with Custom Logic
using AutoMapper; public class CustomerProfile : Profile { public CustomerProfile() { CreateMap<Customer, CustomerDTO>() .ForMember(dest => dest.FullName, opt => opt.MapFrom(src => $"{src.FirstName} {src.LastName}")) .ForMember(dest => dest.Age, opt => opt.MapFrom(src => CalculateAge(src.BirthDate))); } private int CalculateAge(DateTime birthDate) { var today = DateTime.Today; var age = today.Year - birthDate.Year; if (birthDate.Date > today.AddYears(-age)) { age--; } return age; } }
Use AutoMapper in a Controller
[HttpPost] public IActionResult CreateCustomer([FromBody] Customer customer) { var customerDto = _mapper.Map<CustomerDTO>(customer); return Ok(customerDto); }
Sample Response
CreateCustomer Request (Input: Customer)
{ "FirstName": "Jane", "LastName": "Doe", "BirthDate": "1990-05-15" }
CreateCustomer Response (Output: CustomerDTO)
{ "FullName": "Jane Doe", "Age": 34 }
Flattening Complex Objects
Flattening complex objects allows you to simplify nested structures into a flat one.
Define Models and DTOs
public class Order { public int OrderId { get; set; } public DateTime OrderDate { get; set; } public Customer Customer { get; set; } public List<OrderDetail> OrderDetails { get; set; } } public class OrderDetail { public int ProductId { get; set; } public string ProductName { get; set; } public int Quantity { get; set; } public decimal Price { get; set; } } public class OrderDto { public int OrderId { get; set; } public DateTime OrderDate { get; set; } public string CustomerName { get; set; } public string CustomerEmail { get; set; } public List<OrderDetailDto> OrderDetails { get; set; } } public class OrderDetailDto { public int ProductId { get; set; } public string ProductName { get; set; } public int Quantity { get; set; } public decimal Price { get; set; } }
Create a Mapping Profile
using AutoMapper; public class OrderProfile : Profile { public OrderProfile() { CreateMap<Order, OrderDto>() .ForMember(dest => dest.CustomerName, opt => opt.MapFrom(src => src.Customer.Name)) .ForMember(dest => dest.CustomerEmail, opt => opt.MapFrom(src => src.Customer.Email)); CreateMap<OrderDetail, OrderDetailDto>(); } }
Use AutoMapper in a Controller
[HttpPost] public IActionResult CreateOrder([FromBody] Order order) { var orderDto = _mapper.Map<OrderDto>(order); return Ok(orderDto); }
Sample Output
CreateOrder Request (Input: Order)
{ "OrderId": 1001, "OrderDate": "2024-05-15T10:30:00", "Customer": { "Name": "John Doe", "Email": "[email protected]" }, "OrderDetails": [ { "ProductId": 1, "ProductName": "Smartphone", "Quantity": 2, "Price": 500.00 } ] }
CreateOrder Response (Output: OrderDto)
{ "OrderId": 1001, "OrderDate": "2024-05-15T10:30:00", "CustomerName": "John Doe", "CustomerEmail": "[email protected]", "OrderDetails": [ { "ProductId": 1, "ProductName": "Smartphone", "Quantity": 2, "Price": 500.00 } ] }
AutoMapper is an incredibly useful tool for simplifying object mapping and reducing boilerplate code, making your development process much more efficient and maintainable.
- Options Pattern In ASP.NET Core
- Implementing Rate Limiting in .NET
- IExceptionFilter in .NET Core
- Repository Pattern in .NET Core
- CRUD with Dapper in ASP.NET Core
- How to Implement Mediator Pattern in .NET
- How to fix 'asp-controller and asp-action attributes not working in areas'
- Basic Authentication in ASP.NET Core