ASP.NET Core Web API
Lesson 13 of 35 37% of course

Data Transfer Objects (DTOs) & AutoMapper

17 · 8 min · 5/23/2026

Sign in to track progress and bookmarks.

Data Transfer Objects (DTOs) & AutoMapper

Never expose your Database Entity classes directly to the internet. Doing so is a massive security risk (Mass Assignment vulnerabilities) and tightly couples your database schema to your API contract. We solve this by using Data Transfer Objects (DTOs) to act as a secure middleman.

1. Why use DTOs?

❌ The Danger of Returning Entities
public class User 
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string PasswordHash { get; set; } // CRITICAL LEAK!
}

[HttpGet("{id}")]
public ActionResult<User> GetUser(int id) 
{
    // You just leaked the user's password hash to the frontend...
    return _db.Users.Find(id); 
}
✅ The DTO Solution
public class UserResponseDto 
{
    public int Id { get; set; }
    public string Name { get; set; }
    // No PasswordHash field here!
}

[HttpGet("{id}")]
public ActionResult<UserResponseDto> GetUser(int id) 
{
    var user = _db.Users.Find(id);
    return new UserResponseDto { Id = user.Id, Name = user.Name }; 
}

2. Introducing AutoMapper

Manually mapping properties from an Entity to a DTO (as shown above) becomes incredibly tedious when objects have 50 properties. AutoMapper is an industry-standard library that automates this property-to-property copying.

dotnet add package AutoMapper.Extensions.Microsoft.DependencyInjection

Step 1: Create a Mapping Profile

using AutoMapper;

public class UserMappingProfile : Profile
{
    public UserMappingProfile()
    {
        // Source -> Destination
        CreateMap<User, UserResponseDto>();
        
        // Destination -> Source (Useful for POST requests)
        CreateMap<UserCreateDto, User>();
    }
}

Step 2: Register in Program.cs

// This automatically finds all classes inheriting from "Profile" and registers them
builder.Services.AddAutoMapper(typeof(Program));

Step 3: Use IMapper in the Controller

[ApiController]
[Route("api/users")]
public class UsersController : ControllerBase
{
    private readonly ApplicationDbContext _db;
    private readonly IMapper _mapper;

    public UsersController(ApplicationDbContext db, IMapper mapper)
    {
        _db = db;
        _mapper = mapper;
    }

    [HttpGet]
    public async Task<ActionResult<IEnumerable<UserResponseDto>>> GetUsers()
    {
        var users = await _db.Users.ToListAsync();
        
        // AutoMapper magically converts the List of Entities into a List of DTOs!
        var dtos = _mapper.Map<IEnumerable<UserResponseDto>>(users);
        
        return Ok(dtos);
    }
}

3. Interview Mastery

Q: "AutoMapper's `_mapper.Map` happens in Application Memory. If we have 10,000 users in the database but the frontend only needs 2 columns (Id and Name), does AutoMapper cause an inefficient SQL Query (SELECT *) before mapping?"

Architect Answer: "Yes, if used incorrectly. If you run `await _db.Users.ToListAsync()` first, EF Core downloads every column (including heavy Photo byte[] columns) into RAM resulting in a `SELECT *`, and only THEN does AutoMapper strip them away into the DTO. To fix this, AutoMapper provides the `.ProjectTo<TDto>()` extension method. Instead of pulling data into RAM, `ProjectTo` intercepts the LINQ query and rewrites the physical SQL generated by EF Core into a highly optimized `SELECT Id, Name FROM Users`, downloading only the exact bytes necessary across the network."

Test your knowledge

Quizzes linked to this course—pass to earn certificates.

Browse all quizzes
ASP.NET Core Web API

On this page

1. Why use DTOs? 2. Introducing AutoMapper 3. Interview Mastery
1. Fundamentals & HTTP
Introduction to ASP.NET Core Web API REST Principles and HTTP Methods Controllers & ControllerBase Routing (Attribute vs Conventional) Action Return Types (IActionResult)
2. Request Handling
Model Binding (FromQuery, FromBody, FromRoute) Dependency Injection (DI) Deep Dive App Settings & The Options Pattern
3. Data Access & Architecture
EF Core Setup in Web API DbContext & Migrations Repository & Unit of Work Pattern Asynchronous Programming (async/await)
4. Data Transfer & Validation
Data Transfer Objects (DTOs) & AutoMapper Model Validation (DataAnnotations) FluentValidation Integration
5. Advanced Concepts
Global Exception Handling Middleware Content Negotiation (JSON vs XML) Pagination & Filtering Advanced Searching & Sorting HATEOAS (Hypermedia) Implementation Output Caching & Response Caching
6. Security & Authorization
Cross-Origin Resource Sharing (CORS) JWT Authentication Setup Access Tokens & Refresh Tokens Workflow Role-Based & Policy-Based Authorization API Key Authentication Rate Limiting & Throttling
7. Documentation & Testing
Swagger & OpenAPI Configuration Customizing API Documentation Unit Testing Controllers (xUnit & Moq) Integration Testing (WebApplicationFactory)
8. Microservices & Deployment
Consuming External APIs (IHttpClientFactory) Health Checks & Diagnostics API Versioning Strategies Deploying APIs (Docker & Azure)