Data annotations in ASP.NET Core are a set of attributes that can be applied to model properties to specify validation rules, formatting, and display information. They provide a simple way to enforce rules on data models, ensuring that the data meets certain criteria before it is processed or stored. Data annotations are part of the System.ComponentModel.DataAnnotations namespace and are widely used in ASP.NET Core applications for model validation and user input handling.

Key Features of Data Annotations

  • Validation: Data annotations allow you to define validation rules directly on model properties, such as required fields, string length limits, and range constraints.
  • Display Attributes: You can use data annotations to specify how data should be displayed in views, including formatting and display names.
  • Custom Validation: You can create custom validation attributes to implement complex validation logic that is not covered by built-in annotations.

Commonly Used Data Annotations

  • [Required]: Specifies that a property must have a value.
  • [StringLength(maximumLength)]: Limits the length of a string property.
  • [Range(minimum, maximum)]: Specifies a range of valid values for a numeric property.
  • [EmailAddress]: Validates that a property contains a valid email address.
  • [RegularExpression(pattern)]: Validates that a property matches a specified regular expression pattern.
  • [Display(Name = "Display Name")]: Specifies a display name for a property.

Creating a Model with Data Annotations

To demonstrate the use of data annotations, let's create a simple model class that represents a product. We will apply various data annotations to enforce validation rules.

        
using System.ComponentModel.DataAnnotations;

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

[Required(ErrorMessage = "Product name is required.")]
[StringLength(100, ErrorMessage = "Product name cannot exceed 100 characters.")]
public string Name { get; set; }

[Range(0.01, 10000.00, ErrorMessage = "Price must be between 0.01 and 10,000.00.")]
public decimal Price { get; set; }

[EmailAddress(ErrorMessage = "Invalid email address.")]
public string SupplierEmail { get; set; }
}

Explanation of the Model Code

In the Product class:

  • Properties: The class defines four properties: Id, Name, Price, and SupplierEmail.
  • Data Annotations:
    • The [Required] attribute on the Name property ensures that a product name must be provided. If it is missing, a validation error will occur with the specified error message.
    • The [StringLength(100)] attribute limits the length of the product name to 100 characters, providing a custom error message if the validation fails.
    • The [Range(0.01, 10000.00)] attribute specifies that the Price must be between 0.01 and 10,000.00, with a custom error message for invalid values.
    • The [EmailAddress] attribute validates that the SupplierEmail property contains a valid email address format.

Using the Model in a Controller

Once the model is defined, you can use it in a controller to handle HTTP requests and validate the incoming data. Below is an example of a controller that uses the Product model.

        
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;

[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
private static List<Product> products = new List<Product>();

// Action method to create a new product
[HttpPost]
public IActionResult CreateProduct([FromBody] Product product)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState); // Returns a 400 Bad Request if the model is invalid
}

product.Id = products.Count + 1; // Assign a new ID
products.Add(product); // Add the new product to the list
return CreatedAtAction(nameof(GetProductById), new { id = product.Id }, product); // Returns a 201 Created response
}

// Action method to get a product by ID
[HttpGet("{id}")]
public IActionResult GetProductById(int id)
{
var product = products.Find(p => p.Id == id);
if (product == null)
{
return NotFound(); // Returns a 404 Not Found response
}
return Ok(product); // Returns the product as a JSON response
}
}

Explanation of the Controller Code

In the ProductsController class:

  • CreateProduct Action: This action method accepts a Product object from the request body. The [FromBody] attribute indicates that the model binder should look for the data in the request body. If the model state is invalid (e.g., required fields are missing or values are out of range), it returns a 400 Bad Request response with validation errors.
  • GetProductById Action: This method retrieves a product by its ID. If the product is not found, it returns a 404 Not Found response; otherwise, it returns the product as a JSON response.

Conclusion

Data annotations in ASP.NET Core provide a powerful and flexible way to enforce validation rules and display information for model properties. By using built-in attributes, developers can ensure that user input is valid and meets specific criteria before processing it. This approach enhances the security and reliability of applications while simplifying the validation process.