ASP.NET Core 8 Web API -

Models

In ASP.NET Core 8 Web API, models are the objects that represent the data in your application. Models are used to transfer data between the controller and the view or the controller and the data store. This guide covers everything you need to know about creating and using models, including best practices, examples, and detailed explanations.


1. Introduction to Models

Models in ASP.NET Core 8 Web API serve as the foundation for the application's data structure. They encapsulate the data and the business logic to manage that data. Models typically consist of properties and validation attributes to ensure the integrity of the data.


2. Creating Models

Models are usually created as plain C# classes in the Models folder of your project. Each model represents an entity in your application, such as a Product, Order, or Customer.

Example: Product Model
        
            
public class Product
{
    public int Id { get; set; }

    [Required]
    [StringLength(100)]
    public string Name { get; set; }

    [Required]
    [Range(0.01, 10000.00)]
    public decimal Price { get; set; }

    public string Description { get; set; }
}

        
    

3. Data Annotations for Validation

ASP.NET Core provides data annotations to apply validation rules to your models. These annotations ensure that the data meets certain criteria before it is processed or stored.

Common Data Annotations

Example: Customer Model with Data Annotations

        
            
public class Customer
{
    public int Id { get; set; }

    [Required]
    [StringLength(50)]
    public string FirstName { get; set; }

    [Required]
    [StringLength(50)]
    public string LastName { get; set; }

    [Required]
    [EmailAddress]
    public string Email { get; set; }

    [Phone]
    public string PhoneNumber { get; set; }
}

        
    

4. Using Models in Controllers

Models are used in controllers to bind data from HTTP requests. ASP.NET Core automatically binds JSON or form data from the request to the model properties.

Example: Using Models in a Controller
        
            
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    private readonly IProductService _productService;

    public ProductsController(IProductService productService)
    {
        _productService = productService;
    }

    [HttpGet("{id}")]
    public ActionResult<Product> GetById(int id)
    {
        var product = _productService.GetById(id);
        if (product == null)
        {
            return NotFound();
        }
        return Ok(product);
    }

    [HttpPost]
    public ActionResult<Product> Create(Product product)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        _productService.Add(product);
        return CreatedAtAction(nameof(GetById), new { id = product.Id }, product);
    }

    [HttpPut("{id}")]
    public IActionResult Update(int id, Product product)
    {
        if (id != product.Id)
        {
            return BadRequest();
        }

        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        _productService.Update(product);
        return NoContent();
    }

    [HttpDelete("{id}")]
    public IActionResult Delete(int id)
    {
        var product = _productService.GetById(id);
        if (product == null)
        {
            return NotFound();
        }

        _productService.Delete(id);
        return NoContent();
    }
}

        
    

5. Best Practices for Models


6. Using Data Transfer Objects (DTOs)

DTOs are used to encapsulate data and transfer it between layers. They help to decouple the internal representation of data from the way it is exposed to the client.

Example: Product DTO
        
            
public class ProductDto
{
    public int Id { get; set; }

    [Required]
    [StringLength(100)]
    public string Name { get; set; }

    [Required]
    [Range(0.01, 10000.00)]
    public decimal Price { get; set; }

    public string Description { get; set; }
}

        
    
Example: Using DTOs in a Controller
        
            
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    private readonly IProductService _productService;
    private readonly IMapper _mapper;

    public ProductsController(IProductService productService, IMapper mapper)
    {
        _productService = productService;
        _mapper = mapper;
    }

    [HttpGet("{id}")]
    public ActionResult<ProductDto> GetById(int id)
    {
        var product = _productService.GetById(id);
        if (product == null)
        {
            return NotFound();
        }
        var productDto = _mapper.Map<ProductDto>(product);
        return Ok(productDto);
    }

    [HttpPost]
    public ActionResult<ProductDto> Create(ProductDto productDto)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        var product = _mapper.Map<Product>(productDto);
        _productService.Add(product);

        var createdProductDto = _mapper.Map<ProductDto>(product);
        return CreatedAtAction(nameof(GetById), new { id = createdProductDto.Id }, createdProductDto);
    }

    [HttpPut("{id}")]
    public IActionResult Update(int id, ProductDto productDto)
    {
        if (id != productDto.Id)
        {
            return BadRequest();
        }

        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        var product = _mapper.Map<Product>(productDto);
        _productService.Update(product);

        return NoContent();
    }

    [HttpDelete("{id}")]
    public IActionResult Delete(int id)
    {
        var product = _productService.GetById(id);
        if (product == null)
        {
            return NotFound();
        }

        _productService.Delete(id);
        return NoContent();
    }
}

        
    

7. Using AutoMapper

AutoMapper is a library that helps to simplify the mapping between domain models and DTOs. It reduces the boilerplate code needed to manually map properties between objects.

Example: AutoMapper Configuration
        
            
public class AutoMapperProfile : Profile
{
    public AutoMapperProfile()
    {
        CreateMap<Product, ProductDto>();
        CreateMap<ProductDto, Product>();
    }
}

        
    

Registering AutoMapper in Startup.cs

        
            
public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
        services.AddAutoMapper(typeof(Startup));
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseRouting();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }
}

        
    

Differences Between Models and DTOs

1. Purpose: 2. Usage: 3. Separation of Concerns:

When to Use Models and DTOs

Use Models when: Use DTOs when:

8. Best Practices


9. Summary

Models are a fundamental part of ASP.NET Core 8 Web API, representing the data and its structure. By following best practices and using tools like data annotations, DTOs, and AutoMapper, you can ensure that your application's data layer is robust, maintainable, and scalable.