Model binding best practices

An entity object is an EF concept; each entity object maps to a table in the database. A model object is an MVC concept; it is the data structure of HTTP requests and responses. HTTP requests carry data through URL parameters, forms, headers, JSON payloads, and so on. This data is ultimately bound into model objects, and after the model is converted to an entity object, it is persisted to the database.

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
}
public class ProductModel
{
    public string Name { get; set; }
    public decimal Price { get; set; }
}
public class ProductController : Controller
{
    private readonly ShopDbContext _context;

    public ProductController(ShopDbContext context)
    {
        _context = context;
    }

    [HttpPost]
    public async Task<IActionResult> Create(ProductModel model)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        var product = new Product
        {
            Name = model.Name,
            Price = model.Price
        };

        _context.Products.Add(product);
        await _context.SaveChangesAsync();

        return CreatedAtAction(nameof(Get), new { id = product.Id }, product);
    }
}

Different HTTP operations should use different model objects, such as a create model, an update model, a query model, and a delete model. The benefit is a clearer separation of responsibilities: the create model only contains the fields needed for creation, the update model only the fields needed for updating, the query model only the fields needed for querying, and the delete model only the fields needed for deletion. With single responsibilities, maintainability improves, and each model can also provide its own validation rules.

model-entity-mapper