.NET Core Web API Data validation with FluentValidation

In this article, we will learn .NET Core Web API Data validation with FluentValidation.

What is Data Validation in Web API?

Data Validation simply tells the rules and validation that we apply on Data.

Data Validation in Web API means, validate the data that is being sent by client and if the data is not in desired format then send a message to the client about the error.

To understand the Data Validation in Web API, let’s create a model class and name it Product and add 3 property as shown in below code snippet.

public class Product
    {
        public string ProductCode { get; set; }
        public int Stock { get; set; }
        public string ProductName { get; set; }
    }

Create a ProductController class and add a Post method which accepts Product model as input parameter.

Now, before posting the data to the server we need to check if all property of model class is in correct format.

For example – Product Code field should not be blank, Stock must be greater than 0 (zero).

In below code snippet, I have checked ProductCode and if it is blank or null then send 400 (Bad Request) message to the client.

// POST api/<ProductController>
        [HttpPost]
        public IActionResult Post(Product product)
        {
            if(string.IsNullOrEmpty(product.ProductCode))
            {
                return BadRequest();
            }

            return Ok();
        }

In case ProductCode is blank then client will receive below response.

{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "Bad Request",
  "status": 400,
  "traceId": "00-3738488015a04444b4f6f4b71938b168-591299b77d6d5344-00"
}

The above response doesn’t describe the exact error details.

To show exact error details, we will use ModelState as shown in below code snippet.

 // POST api/<ProductController>
        [HttpPost]
        public IActionResult Post(Product product)
        {
            if(string.IsNullOrEmpty(product.ProductCode))
            {
               
                ModelState.AddModelError(nameof(product.ProductCode),
                    $"{nameof(product.ProductCode)} Can not be blank.");
                return BadRequest(ModelState);
            }

            return Ok();
        }

Now, client will receive below error message in case ProductCode is blank.

{
  "ProductCode": [
    "ProductCode Can not be null"
  ]
}

What is ModelState?

ModelState is a property available in instance of a controller class. It is a collection of name and value pairs which are submitted to the server while doing POST operation. It also contains error message, if any.

So, in this way if we have multiple properties to check then we need to write code as shown below.

if (string.IsNullOrEmpty(product.ProductCode))
            {
                ModelState.AddModelError(nameof(product.ProductCode),
                                $"{nameof(product.ProductCode)} Can not be null");
                return BadRequest(ModelState);
            }

            if (string.IsNullOrEmpty(product.ProductName))
            {

                ModelState.AddModelError(nameof(product.ProductName),
                    $"{nameof(product.ProductName)} Can not be null");
                return BadRequest(ModelState);
            }

            if (product.Stock <= 0)
            {

                ModelState.AddModelError(nameof(product.Stock),
                    $"{nameof(product.Stock)} Can not be 0");
                return BadRequest(ModelState);
            }

This is little bit lengthy and complex task.

FluentValidation

FluentValidation is a .NET framework based library which helps to build strong type validation rules. It supports .NET standard and .NET Core framework both.

FluentValidation nuget Packages

To start working with FluentValidation, we need to install below packages from nuget package manager.

  • FluentValidation
  • FluentValidation.AspNetCore
  • FluentValidation.DependencyInjectionExtensions

Code snippet for FluentValidation

Create a class and inherit it from AbstractValidator<T>. Here T is the model class.

You need to use below namespace.

using FluentValidation;
public class ProductValidator:AbstractValidator<Product>
    {
        public ProductValidator()
        {
            RuleFor(x => x.ProductCode).NotEmpty();
            RuleFor(x => x.ProductName).NotEmpty();
            RuleFor(x => x.Stock).GreaterThan(0);
        }
    }

Now, write below code in Action method.

Create the object of Validator class and then use ValidationResult class to fetch the result.

IsValid – Returns boolean value which says if the validation is succeeded.

[HttpPost]
        public IActionResult Post(Product product)
        {
            ProductValidator validationRules = new ProductValidator();
            ValidationResult validationResult = validationRules.Validate(product);
            string message = "";
            if (!validationResult.IsValid)
            {
                foreach (var failure in validationResult.Errors)
                {
                    message = message + "Property " + failure.PropertyName + " failed validation. Error was: " + failure.ErrorMessage;
                }

                return BadRequest(message);
            }

            return Ok();
        }

You can return the error message in your way. So, by using FluentValidation we have minimize the code and achieved the validation status with built-in methods and rules.

Hope you like this article.

Please follow and like us:

Leave a Comment