Microservices part 3

In this article, we’ll discuss about Data Annotation and Fluent Validation. This article only covers about validation part such as validation using data annotation, Custom validation using data annotation and Fluent validation.
https://anuphosur.wordpress.com/2020/03/29/microservices-part-2/
https://anuphosur.wordpress.com/2020/03/29/microservices-part-1/

Getting Started with Data Annotation

Firstly, let’s understand, what is Data Annotation?
Data Annotation are the attributes to enforce rules to the entity classes or to the properties. Data Annotation attributes can be found in System.ComponentModel.DataAnnotations and System.ComponentModel.DataAnnotations.Schema.

Let’s not repeat the same stuff on attributes available in other website on System.ComponentModel.DataAnnotations and System.ComponentModel.DataAnnotations.Schema. Please refer to the below article
https://www.entityframeworktutorial.net/code-first/dataannotation-in-code-first.aspx

Let’s begin with simple example data annotation.

In the previous article, we were able to send empty/null value to the email id. In order to make email id field as mandatory, we need to use Required attribute.

[Required(ErrorMessage = "Please enter Email Id”)]
public string EmailId { get; set; }

Now, email id field is mandatory but we still can use invalid format. In order to correct the format, EmailAddress attribute has to be added to EmailId property.

[Required(ErrorMessage = "Please enter Email Id"),EmailAddress(ErrorMessage ="Please enter valid email id")]
public string EmailId { get; set; }

We can also use Range attribute for setting the minimum value to the maximum value.

[Required(ErrorMessage = "Please enter salary"),Range(1000,double.MaxValue,ErrorMessage ="Please enter salary greater than 1000")]
public double Salary { get; set; }

Assuming, we have to create custom validation attribute then we can do it easily by inheriting ValidationAttibute class.

public class PhoneNumberAttribute:ValidationAttribute
{
public PhoneNumberAttribute()
{
}

public override bool IsValid(object value)
{
var phoneNumber = ((int)value).ToString();
return phoneNumber.Length >= 9 && phoneNumber.Length <= 10;
}
}

You need to mark PhoneNumber with our PhoneNumber attribute

[Required(ErrorMessage = "Please enter phone number"),PhoneNumber(ErrorMessage ="Invalid Number")]
public int PhoneNumber { get; set; }

Getting Started with Fluent Validation

Fluent Validation allows you to separate validation rules from your model and the structure of rules makes it nice and readable. It also helps us to write unit tests in much simpler way.

First we need to bring FluentValidation.aspnetcore from the nuget. We can then wire this up in startup’s configuration services method by using AddFluentValidation in AddMVC

public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddDbContext(options =>
{
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
});
services.AddMvc().AddFluentValidation(x => x.RegisterValidatorsFromAssemblyContaining());
}

Simple Rules:

Fluent API supports few built in validation rules such as NotEmpty, EmailAddress etc

public class EmployeeValidator:AbstractValidator
{
public EmployeeValidator()
{
RuleFor(x => x.FirstName).NotEmpty().WithMessage("Please enter first name");
RuleFor(x => x.LastName).NotEmpty().WithMessage("Please enter last name");
RuleFor(x => x.EmailId).NotEmpty().WithMessage("Please enter email")
.EmailAddress().WithMessage("Please enter valid Email");
RuleFor(x => x.Salary).NotEmpty().WithMessage("Please enter salary")
.GreaterThan(1000).WithMessage("Salary should be greater than 1000");
}
}

Conditional Rules

Let’s go through few of the complex conditions but I can’t perform any logical condition. So I went up with some crazy rules. You can try some conditional rules ex: adding country property to the employee and for India the phone number is 10 whereas for Ireland the phone number is 9.

RuleFor(x => x.FirstName).NotEmpty().WithMessage("Please enter first name")
.When(x=>x.LastName.ToUpper()=="HOSUR").WithMessage("You are showcasing yourself Anup!");

Custom Rules

Finally, we will create custom rules for the PhoneNumber property. Similar to what we have performed in the Data Annotation section.

We defined a rule like this below

I have created extension method as this can be completely reused for all the data types.

public class PhoneNumberValidation:PropertyValidator
{
public PhoneNumberValidation():base("Phone number is not valid")
{
}

protected override bool IsValid(PropertyValidatorContext context)
{
var phoneNumber=(Convert.ToInt32(context.PropertyValue)).ToString();
if (!string.IsNullOrEmpty(phoneNumber))
{
return phoneNumber.Length >= 9 && phoneNumber.Length <= 10;
}
return false;
}

Extension method is used for validating the phone number.

public static class CustomvalidatorExtension
{
public static IRuleBuilderOptions ValidatePhoneNumber(this IRuleBuilder ruleBuilder)
=> ruleBuilder.SetValidator(new PhoneNumberValidation());
}

Rules can be added to PhoneNumber attribute of the Employee class

RuleFor(x => x.PhoneNumber).NotEmpty().WithMessage("Please enter phone number")
.ValidatePhoneNumber().WithMessage("Please enter valid phone number");

In the next article, we will see how to use Fluent Api in EF core.

I hope you like the article.

One thought on “Microservices part 3

  1. Pingback: Azure App Service and Diagnostic logging using asp.net core – Articles on latest .net technology

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s