FluentValidation for Powerful ASP.Net Core Model Validation | Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome along my name is chris and in this video i'll show you how you can add intuitive flexible model validation to your asp.net core project using the fluent validation library now the example i'll be using in this video is a web api project but the implementation is very similar to mvc if this is your first time here and you like this kind of content if it's useful to you please do consider subscribing and tapping the bell icon below to receive notifications with that let's get started i have an asp.net core web api project that is going to be the back end for a very important and unique to-do list app tasks are represented by a task item model that has the following properties a description of the task which is a string a due date a date time of course a flag remind me which the user can set to true if they want to receive a reminder just before their task is due we have a nullable integer reminder minutes before due this sets how many minutes before the task is due a reminder is sent if the remind me flag is true and finally we have a simple list of strings that the user can set to specify sub items on the task i've also created a tasks controller with a post endpoint that will allow consumers of my api to create new tasks on their to-do lists my post endpoint takes a task item instance as a parameter which the mvc model binder will attempt to create from the incoming post request body at the moment i'm using the out of the box default model binder and model validation and the problem with this is that if i were to send a blank request into my post endpoint the model binder would create a task item with an empty description and a date time with a min value it also wouldn't perform any validation on the checklist or the requested value on the minutes before due field i could of course use the built-in asp.net core validation attributes to achieve some of this but i want a lot more flexibility than they allow and i want to be able to create some advanced validation rules so i'll use the fluent validation package instead i've installed the fluent validation package for asp.net core using the command dot net add package fluentvalidation.asp core this package includes fluent validation and all of the extra good stuff required to work with and plug into asp.net core's middleware pipeline so with fluent validation instead of adding attributes to our task item class directly we'll define our rules on a new class which inherits from a special base class called abstractvalidator so let's first add the namespace using fluentvalidation and then create a class task item validator we'll base task item validator on the abstract eval database class and then pass in task item as a type parameter so fluent validation knows to use properties on the task item class now we've added the abstract validator base class we have access to the fluent validation rule engine so first things first we want to make sure that when a user creates a task item the description can never be empty fluent validation as the name suggests gives us a fluent api that we can use to create some very advanced validation rules using method chains so in the constructor 4 task item validator we'll use the rule 4 method on our base class to start a chain of rules for our description we can select the description using a link expression where t is a task item so we can now add validators to our description field using extension methods on the rule four so we can call not empty which appends the not empty validator to our description so fluent validation will check the description field to make sure it is not empty and if it is it will add a validation error to our response we now want to make sure that when a user created task item the due date is valid and not in the past so let's start a new method chain for due date and let's drop down to a new line and we want to check if the due date is greater than or equal to today so we'll use the greater than or equal to validator and we'll pass in date time dot today now if a user sends a request that fails validation fluent validation will also generate error messages for us but they might not always be what we want them to be so we can specify a custom error message to show when the greater than or equal to validation rule fails using the extension method with message i'm just going to say due date must be in the future now notice we also have a flag remind me that the user can set if they want to receive a reminder when their task is due now if this flag is true then ideally we need to know how long before the task is due to send the reminder we could just set a rule for the reminding minutes before due to make sure it was always set however this would apply even if the user had not set the remind me flag to true as it wouldn't really make any sense so what we can do is conditionally apply rules to the reminder minutes before due property only if the reminder flag is set to true to do this we can use another method on the abstractval database class which is called when so we can call when and the first parameter is an expression that must return true for the rest of the block to run so we want to say that when the remind me flag is true then run this action so inside this action we can now apply rules to our reminder minutes before do field that will only be applied if the remind me flag is set to true first things first let's handle situations when reminding minutes before due is null using a rule for and then adding the not null validator and let's specify a custom message remind a minute before do must be set so next we want to make sure that the value for reminding minutes before due is positive so we can now train a greater than validator and we just pass in zero here and we can add a friendly error message reminding minutes for you must be greater than zero so finally we want to only allow users to specify remind intervals in multiples of 15 minutes so we want validation to fail for any integer that isn't a multiple of 15 so only allow 15 30 45 and so on for this fluent validation allows us to specify a bit of custom validation logic using the must method if must return is false the validation rule will fail if two it will pass so we can chain the must validator and this is essentially a func expression that receives the value of minutes before due as a parameter so we can just return true if value is evenly divisible by 15 without a nice friendly error message must be a multiple 15. so let's leave our when block and have a look at our sub items list we want to make sure that a user cannot pass an empty string into the sub items array if we were to use the rule for call on the sub items property in this case then we will be specifying rules for the list itself not the items within it we want to validate the strings inside the list and for this fluent validation gives us the rule for each method we use is the same as rule 4 but any subsequent rules in the rule for each chain are applied to each of the items within the collection not the collection itself so when we call rule for each and select our sub items array then the next rule in the chain will apply to a string so let's add the not empty validator and then once again we can add a custom message and that's it for our validation rules we've ensured that our description cannot be empty we ensure that our due date is always greater than today we've made sure that when the remind me flag is set to true then the reminder minutes before due field is not null greater than 0 and is always an even multiple of 15. and finally we've added a rule to check to make sure that values in the sub items array cannot be empty so to use these validation rules when model binding on our post endpoint we don't need to add any attributes to our controller or to our action but we do need to tell asp.net where to find them so to do that let's head over to our startup.cs file so fluent validation is middleware that we need to add to asp.net's middleware pipeline so first we'll add a new using statement using fluentvalidation.asp.net core next in our configure services method we can add the extension method add fluent validation after our add controllers call and this will work but there are two more problems first we want to prevent our application from applying any of its own default validation to the model binding process and second we also need to tell asp.net about our validators so it knows when model binding a type task item to use our task item validator so we'll open up the fluent validation call and pass in an action fv fv is our fluent validation configuration and first we'll disable the default mvc validation so we just set the snappily named run default mvc validation after fluent validation executes flag to false and this does exactly where this isn't the tin it just prevents mvc from running its own default validation after fluent validation has run next we'll call the register validators from assembly containing method and pass in our startup class this will tell fluent validation to go through our whole assembly and register any validators it finds and use them when model binding and that's it we have our validator we have our post endpoint and we've told asp.net to use fluent validation and so let's go test our validation using postman so we now have our api running in debug mode in the background we want to test our validation rules and we do that using postman so first things first let's see what happens when we send an empty body up to our endpoint so we have an empty json body here ready to send we'll hit send first off we notice we received a 400 bad request response this is good this means we failed validation and fluent validation has even formatted our error messages into an array for us next we see we've tripped the greater than or equal to rule on our due date and our not empty rule on our description so let's modify the request to add in a description on a due date now let's set our remind me flag to true we want to test our reminding minutes before due rules so if we send that up to our api we'll see that due date and description have pass validation but this is where things get really cool now we've set remind me to true fluent validation has run the code in our when block and applied rules to reminding minutes before due that otherwise would have been skipped we can also see that both our multiple of 15 check and our greater than zero check have both failed so let's fix that but also add some sub items to test the sub items validator and now we have a sub items array with an empty string in it let's see what happens so fluent validation has now checked our sub items array and see that the second value is empty now if we fix that and remove the second item and resend our request all of our validation rules should pass and we'll hit the breakpoint in our post endpoint now we're back in vs code and we've hit our breakpoint so let's have a look at what the mvc model binder has given us on our task item model so great all of our properties are present and correct description is a string due date is in the future i remind me flag is true and reminding minutes before due is a positive integer with a multiple of 15 and if we look in our sub items array we'll see that we have one item which is a non-empty string everything has worked perfectly and our validation rules have prevented a badly formatted model from being posted there's so many other features packed into fluent validation that i couldn't cover them all in one video so i've linked the documentation below where you can find out more including a full list of all the validators that you can use the code in this example is up on my github 2 so you can check that out if you like thank you so much for watching like the video please do subscribe if you haven't already i'll see you in the next video [Music] you
Info
Channel: Roberts Dev Talk
Views: 3,577
Rating: 5 out of 5
Keywords: asp.net core model validation, asp.net core web api model validation, asp.net core, web api, fluentvalidation, fluent validation, fluentvalidation .net core api, asp.net core request validation
Id: Nw5iLDxhEAA
Channel Id: undefined
Length: 13min 23sec (803 seconds)
Published: Thu Mar 11 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.