Skip to content

Custom Validate Model Attribute

Shady Ashraf Abdelhameed edited this page Jan 31, 2025 · 1 revision

Custom Action Filters for Model Validation

In ASP.NET Core, we can improve the maintainability and cleanliness of our controller methods by using custom action filters for model validation. Instead of checking ModelState.IsValid in each controller action, a custom action filter centralizes the logic, reducing redundancy and keeping controller methods clean.


Steps to Implement Custom Action Filter

1. Create a Folder for Custom Filters

Organize your project by creating a dedicated folder for action filters.

  • Right-click on the project.
  • Add a new folder named CustomActionFilters.

2. Add a Custom Action Filter Class

Create a new class inside the CustomActionFilters folder.

Example: ValidateModelAttribute.cs

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;

namespace YourNamespace.CustomActionFilters
{
    public class ValidateModelAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            if (!context.ModelState.IsValid)
            {
                context.Result = new BadRequestObjectResult(context.ModelState);
            }
        }
    }
}

  • ActionFilterAttribute: Provides a base class for custom action filters.
  • OnActionExecuting: Executes before the controller action method runs.
  • BadRequestObjectResult: Returns a 400 Bad Request response if the model validation fails.

3. Apply the Custom Action Filter

Decorate controller actions with the ValidateModelAttribute to enable validation.

Example: Controller Before Using the Filter

[HttpPost]
public IActionResult CreateRegion([FromBody] AddRegionRequestDTO request)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }
    // Controller logic...
    return Ok();
}

Example: Controller After Using the Filter

[HttpPost]
[ValidateModel]
public IActionResult CreateRegion([FromBody] AddRegionRequestDTO request)
{
    // Controller logic...
    return Ok();
}

  • Replace repetitive ModelState.IsValid checks with the [ValidateModel] attribute.

4. Apply to Multiple Methods

You can apply the [ValidateModel] attribute to other methods, such as update and delete operations.

Example: Updated Controller

[HttpPost]
[ValidateModel]
public IActionResult CreateRegion([FromBody] AddRegionRequestDTO request)
{
    // Logic for creating region
    return Ok();
}

[HttpPut]
[ValidateModel]
public IActionResult UpdateRegion([FromBody] UpdateRegionRequestDTO request)
{
    // Logic for updating region
    return Ok();
}


Testing the Custom Action Filter

  1. Run the application.
  2. Use an API testing tool like Postman or Swagger to send requests.
  3. Test invalid inputs to ensure the custom action filter catches validation errors.

Example Request:

  • Endpoint: /api/regions
  • Method: POST
  • Body:
{
    "code": "A",
    "name": "Region Name"
}

Example Response:

{
    "errors": {
        "Code": [
            "Code must be at least 3 characters."
        ]
    }
}


Benefits of Using Custom Action Filters

  • Cleaner Code: Removes repetitive validation checks from controller methods.
  • Centralized Logic: Simplifies maintenance and updates to validation logic.
  • Reusable: Easily apply the filter across multiple endpoints.

Conclusion

Using custom action filters in ASP.NET Core enhances code cleanliness and maintainability by handling common logic, like model validation, in a single location. This approach makes controllers more concise and readable while ensuring consistent validation across your API.

Clone this wiki locally