DTO and AutoMapper in asp.net core web api with example
Create Model Classes(Author, Book, AuthorDTO, BookDTO)
public class Author { public int id { get; set; } public string name { get; set; } public string address { get; set; } public string mobile { get; set; } public List<Book> Books { get; set; } } public class AuthorDTO { public int id { get; set; } public string name { get; set; } public List<Book> Books { get; set; } } public class Book { public int id { get; set; } public string BookName { get; set; } public string ISBN { get; set; } public int AuthorId { get; set; } [ForeignKey("AuthorId")] public Author Author { get; set; } } public class BookDTO { public int id { get; set; } public string BookName { get; set; } public int AuthorId { get; set; } [ForeignKey("AuthorId")] public Author Author { get; set; } }
Update Data Context
public class DataContext : DbContext { public DataContext(DbContextOptions<DataContext> options) : base(options) { } public DbSet<Author> Authors { get; set; } public DbSet<Book> Books { get; set; } }
Add Microsoft.AspNetCore.Mvc.NewtonsoftJson Package using NugetPackage Manager.
Run Migration
Add-migration second
Update-database
Startup.cs
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Rest.Models; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Rest { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddControllersWithViews() .AddNewtonsoftJson(options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore ); services.AddSwaggerGen(options => { options.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo { Title = "Swagger Demo APO", Description = "Api with Swagger", Version = "V1" }); }); services.AddDbContext<DataContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), providerOptions => providerOptions.EnableRetryOnFailure())); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseSwagger(); app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "My Test1 Api v1"); }); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } } }
Create New Controller DTOExample and add Following code
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Rest.Models; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Rest.Controllers { [Route("api/[controller]")] [ApiController] public class DTOExampleController : ControllerBase { private readonly DataContext _context; public DTOExampleController(DataContext context) { _context = context; } [HttpGet("{id}")] public IActionResult GetAuthorandBooks(int id) { var data = _context.Authors.Include("Books").FirstOrDefault(y => y.id == id); // var data = _context.Authors.ToList(); return Ok(data); } } }
Now we will use AutoMapper to Add Data Into DTO
AutoMapper
We are going to install AutoMapper in our project. In Visual Studio, in the Package Manager Console you can use the following command:
Install-Package AutoMapper.Extensions.Microsoft.DependencyInjection
Make Changes in above code
Note :- Following Code is not required if we are using simplest approach of AutoMapper but only for HttpGet Request but if we are using POST method using DTO then we required this
Create an new folder(Mapper) in application and add an class
public class AllMappersProfile : Profile { public AllMappersProfile() { CreateMap<Author, AuthorDTO>(); CreateMap<Book, BookDTO>(); } }
Make Changes in ConfigureService method in Startup.cs
//Simplest Approach to Add Auto Mapper is Start services.AddAutoMapper(typeof(Startup)); //Simplest Approach to Add Auto Mapper is End //Auto Mapper Configuration Start //var mapperConfig = new MapperConfiguration(mc => //{ // mc.AddProfile(new AllMappersProfile()); //}); //IMapper mapper = mapperConfig.CreateMapper(); //services.AddSingleton(mapper); //Auto Mapper Configuration End DTO Example Controller
[Route("api/[controller]")] [ApiController] public class DTOExampleController : ControllerBase { private readonly DataContext _context; private readonly IMapper _mapper; public DTOExampleController(DataContext context, IMapper mapper) { _context = context; _mapper = mapper; } [HttpGet("{id}")] public IActionResult GetAuthorandBooks(int id) { //Full Data Return //var data = _context.Authors.Include("Books").FirstOrDefault(y => y.id == id); // Pass Data Into DTO var authordata = _context.Authors.FirstOrDefault(x => x.id == id); var authordtodata = _mapper.Map<AuthorDTO>(authordata); return Ok(authordtodata); } } AutoMapper List Mapping [HttpGet("GetAuthors")] public IActionResult GetAuthors() { var authordata = _context.Authors.ToList(); var authordtodata = _mapper.Map<List<AuthorDTO>>(authordata); return Ok(authordtodata); }
How to Add Entity using Auto Mapper
First Make changes in AutoMapperProfile available in Mapper Folder
public class AllMappersProfile : Profile { public AllMappersProfile() { CreateMap<Author, AuthorDTO>(); CreateMap<Book, BookDTO>(); //For Insertion from DTO to Main Object CreateMap<AuthorDTO, Author>().ForMember(x=>x.Books , options=>options.Ignore()); } }
DTOExample Controller
[HttpPost("AddAuthors")] public IActionResult AddAuthors(AuthorDTO obj) { var added = _context.Add(_mapper.Map<Author>(obj)); _context.SaveChanges(); return CreatedAtAction("GetAuthorandBooks", new { id=obj.id }, obj); }
Swagger Insertion
{ “name”: “John Mass”}