Fluent Validation in Asp.net Web API
Tags: api, aspdotnet, asp, csharp
Published: 2023-04-28 09:27:19

##<u>Introduction</u>

Fluent validation is a validation library for .Net applications that allows developers to implement validation rules. 

This article we'll explore on how to use Fluent Validation with Asp.net Web Api to validate HTTP POST requests.

### <u>Install FluentValidation Nuget Package</u>

Install the .Net library from the Nuget package manager or from the dotnet CLI.

`Tools →Nuget Package Manager → Manage Nuget Packages For Solution `
`
dotnet add package FluentValidation.AspNetCore`

### <u>Create a Model Class</u>
This model class acts as a representation of the data structure in the database.
Our model class --> `Transaction.js`

```python
public class Transaction
    {
        public Guid Id { get; set; } = Guid.NewGuid();  
        public string TransactionName { get; set; }

        public string VendorName { get; set; } 

        public int TransactionCost { get; set; } 

        public int TransactionCostCharges { get; set; }
    }

```



###<u>The Validator Class</u>

```python
public class TransactionValidator:AbstractValidator<Transaction>
 {
     public TransactionValidator()
     {
       RuleFor(exp => exp.TransactionName).NotEmpty().MinimumLength(5).MaximumLength(20);
            RuleFor(exp => exp.TransactionName).Must(exp => !exp.Any(char.IsDigit)).WithMessage("Name should not Contain any Numbers");

     }
 }
```

Fluent Validation provides a base class `AbstractValidator` that provides a set of methods and properties that implements the validation rules that can be inherited and extended.

`public class CreatedClass:AbstractValidator<T>`

`<T>` is the model class created above that we are consuming.

![public class CreatedClass:AbstractValidator<T>  and public class TransactionValidator:AbstractValidator<Transaction>](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1c5h46ebv6au4k0ata36.png)

#####Example 1:

```javascript
RuleFor(exp => exp.TransactionName).NotEmpty().MinimumLength(5).MaximumLength(20);
```
`RuleFor` is one of the methods that implements validation rules for a particular property.
In this Example the `RuleFor` validates the `TransactionName` Property it should not be Empty, with a length between 5 and 20.

#####Example 2:
 
```javascript
RuleFor(exp => exp.TransactionName).Must(exp => !exp.Any(char.IsDigit)).WithMessage("Name should not Contain any Numbers");

```
The `TransactioName` should not contain Numbers and the custom message --> `WithMessage("Name should not Contain any Numbers")` is shown.

_There are many Expressions you could choose from refer to the following fluent validation documentation _<https://docs.fluentvalidation.net/en/latest/index.html>

### <u>Configure the Validator Class</u>


Register the  `TransactionValidator` in the `program.cs` class to make it available for dependancy injection in other classes.

Dependancy injection -->

>  A software design pattern, which is a technique for achieving Inversion of Control (IoC) between classes and their dependencies
[](https://learn.microsoft.com/en-us/dotnet/core/extensions/dependency-injection)
```javascript
builder.Services.AddScoped<TransactionValidator>()
```
### <u>The Controller</u>

Create a new Controller `TransactionController`.

```Python
public class TransactionController : ControllerBase
 {
        public Transactiondb Transactiondb { get; }
        public TransactionValidator Validations { get; }

        public TransactionController(Transactiondb transactiondb ,TransactionValidator T_validations)
        {
            Transactiondb = transactiondb;
            Validations = T_validations;
        }
}
```
The `TransactionController` Extends the `ControllerBase` class.
There two properties the `Transactiondb` class and the `TransactionValidator` class
In the constructor of `TransactionController` both `Transactiondb` and `TransactionValidator` are registered or injected.

####_ Add the HttP Post method_
 
```python
    [HttpPost]
 public async Task<IActionResult> AddNewTransaction([FromBody] Transaction transaction)
       {
    
            var validationResult = await Validations.ValidateAsync(transaction);
            if (!validationResult.IsValid) 
            {
                return   BadRequest(validationResult.Errors);
            }

            var newTransaction = new Transaction
            {
                Id = Guid.NewGuid(),
                TransactionName = transaction.TransactionName,
                TransactionCost = transaction.TransactionCost,
                VendorName = transaction.VendorName,    
                TransactionCostCharges= transaction.TransactionCostCharges, 
            };
           
            await Transactiondb.AddAsync(newTransaction);
            await Transactiondb.SaveChangesAsync();
           return Ok("Transaction added Successfully");;
          
       }

```

 When the client adds a new transaction the  `validate async`method from the `TransactionValidator` performs the validations created on the `transaction` added.

The `validationResult` holds the results. 
If the `validationResult` is invalid method returns a `BadRequest` response with the error message in the response body.

If the validation is successfull the transaction is added to the database and an `Ok`reponse to the client with message `Transaction added Successfully`.

###<u>Testing With Postman</u>
Example 1:
Lets Clear the `TransactionName` 

![HTTP Post Image with Transaction Name empty and an bad request is thrown](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/52cb05v48wa8h1wtgwpj.png)
A `400 Bad request` error Code is thrown with 
**Error Messages** :`Transaction Name' must not be empty` and `The length of 'Transaction Name' must be at least 5 characters. You entered 0 characters`
 shown.

Example 2:
Lets Add a `TransactionName` with Numbers.


![HTTP Post Transaction Name with numbers  and a bad request is thrown  showing the custom Error message](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mmnn1871tvlgwvhs1jnt.png)
**Error Message** :` Name should not Contain any Numbers`

##Valid data:

![Http Post with Vaklid data with message Transaction has been added successfully](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/37bdmm5nan66wm0duuz9.png)
The `200 OK` status code meaning the Transaction has been added to the database.
        
##<u>Conclusion</u>
Validation is very important in API development It helps to ensure that data is valid and secure .FluentValidation has made API validation easy to implement making it a very powerful validation tool.