Validation using MediatR's Pipeline Behaviors and FluentValidation | Clean .NET Core

Sdílet
Vložit
  • čas přidán 4. 12. 2019
  • Become a Patreon and get source code access: / nickchapsas
    Check out my courses: dometrain.com
    Hello everybody I'm Nick and in this ASP.NET Core tutorial I will show you how you can use MediatR's Pipeline Behavior feature to add domain level validation in your API in a very clean way. We will add it using a very intuitive way, without mixing it with our happy path logic in our main IRequestHandler. I will also explain how exactly Pipeline Behaviors work and why they are a perfect fit for this piece of functionality. The validation logic will use FluentValidation.
    Don't forget to comment, like and subscribe :)
    Social Media:
    Follow me on GitHub: bit.ly/ChapsasGitHub
    Follow me on Twitter: bit.ly/ChapsasTwitter
    Connect on LinkedIn: bit.ly/ChapsasLinkedIn
    #aspnetcore #mediatr #tutorial

Komentáře • 102

  • @emmanuelcaamal8201
    @emmanuelcaamal8201 Před 3 lety

    Thanks for the demostration, is a exelent form to initialize with MediatR and CQRS on create API services

  • @TBPer
    @TBPer Před 3 lety

    Awesome video. Well-explained with perfect pace!

  • @gerappa1126
    @gerappa1126 Před 2 lety

    Brilliant work, your videos are precious and clear. Like it!

  • @shreyasjejurkar1233
    @shreyasjejurkar1233 Před 4 lety

    Nice. Looking forward to implementing notifications in the Meditr pattern and using it in project about success or failure operation.

  • @leandrowitzke6405
    @leandrowitzke6405 Před 4 lety

    Amazing video, very clearly. Thanks for sharing

  • @RamiNassarPlus
    @RamiNassarPlus Před 4 lety +8

    Thanks for your dedication to what you do. Will you consider using a zoom in tool whenever you start coding 🙂

  • @MrAbidakhtar
    @MrAbidakhtar Před 4 lety

    Fabulous Nick Just loved it a lot

  • @yaraslauhadunou547
    @yaraslauhadunou547 Před 4 lety

    Cool! Thank you Nick!

  • @davidadler8628
    @davidadler8628 Před 3 lety +23

    Thanks for the great video Nick. In the ValidationBehavior class, you mentioned that you were just throwing the new ValidationException(failures) exception for demonstration simplicity and that you would want to use an error handler pipeline rather than exception in production code. Can you point me to an example of the error handler pipeline?

    • @idan5323
      @idan5323 Před rokem

      I would like to know as well, I know there is an option to validate manually via a Result request object, but it would be nice to know if there is a method with less boiler plate and same performance.
      The only way I can think of is the Asp.Net filters method, but that is not related to mediatr.

  • @lpsoldier357
    @lpsoldier357 Před 3 lety

    Awesome content. Thanks!

  • @sairk6174
    @sairk6174 Před 4 lety

    Great Nick !!

  • @F2H16
    @F2H16 Před 3 lety

    It's a great video.Thanks a lot.

  • @talkathiriify
    @talkathiriify Před 4 lety

    Very Awesome
    Thank you very much.

  • @jamesbarlow6523
    @jamesbarlow6523 Před 3 lety +4

    Great video Nick!
    In a future video it would be really nice to see how to properly apply testing when using MediatR and the CQRS pattern.

    • @jasonleandro412
      @jasonleandro412 Před 2 lety

      you all probably dont care at all but does someone know a tool to get back into an Instagram account..?
      I stupidly forgot my login password. I appreciate any tips you can give me.

    • @abdullahdanny9420
      @abdullahdanny9420 Před 2 lety

      @Jason Leandro instablaster ;)

    • @jasonleandro412
      @jasonleandro412 Před 2 lety

      @Abdullah Danny thanks so much for your reply. I found the site through google and im waiting for the hacking stuff now.
      Looks like it's gonna take a while so I will get back to you later with my results.

    • @jasonleandro412
      @jasonleandro412 Před 2 lety

      @Abdullah Danny It worked and I finally got access to my account again. Im so happy:D
      Thanks so much you saved my account !

    • @abdullahdanny9420
      @abdullahdanny9420 Před 2 lety

      @Jason Leandro Happy to help =)

  • @toastybowl
    @toastybowl Před 3 lety +2

    @13:53 "...& Keep in mind this is domain-level validation!.."
    Been wondering how to do this simply with fluent validator for a while & it turns out Mediatr was the this missing link all along.
    Great point + easy to miss for those used to only this endpoint-level/DTO validator usage which is far more common in experience

    • @zabustifu
      @zabustifu Před rokem

      DTO validation makes sense to me, considering validating domain models means your API would be returning bad requests for a different model than what was sent to your API. In the video here, it's simple because there are just two properties in the request models, but if your DTOs don't match the domain models, then your bad requests will be confusing for your API callers. In theory, it might make sense to have two validation logics (DTO validation + domain model validation), but in practice, that sounds really overkill unless you've got a very complex solution.

  • @techdeceptive
    @techdeceptive Před 2 lety

    Thank you Boss!

  • @benjamincharlton3774
    @benjamincharlton3774 Před 3 lety +5

    I love these videos. I'm learning so much about modern patterns and practices after a long break from professional programming. Thank you! I tried to adapt the pattern in this video so as not to throw a validation exception (as you recommended yourself) but I found it to be very difficult and didn't find any good examples on the internet. Is there a pattern you recommend? Do you still believe it's important not to throw a costly ValidationException to signal an invalid command?

    • @mohammadjaber3898
      @mohammadjaber3898 Před rokem

      i returned a solid state result contains my result info instead of throwing exceptions
      Result : is my Return Result Class contains a method named Feiler to hold the error information
      this code is not optimized yet but i hope it the startup answer for not using exceptions
      if (failures.Any())
      {
      var errors = failures.Select(p => p.ErrorMessage).ToArray();
      if(typeof(TResponse).Name.Contains("Result"))
      {
      MethodInfo builderMethod = typeof(TResponse).GetMethod("Failure", BindingFlags.Static | BindingFlags.Public);
      var res = (TResponse)builderMethod.Invoke(null, new object[] { errors });
      return res;
      }

      }

  • @moonbiscuit8742
    @moonbiscuit8742 Před 4 lety

    cool and clean

  • @davidprice350
    @davidprice350 Před 3 lety +1

    As you mentioned Domain level validation; would you implement a validator for say "User does not exist" during a login process? If not, how would you implement this at the Handler level?

  • @clarke8226
    @clarke8226 Před 7 měsíci

    Thanks for the great content and videos, by the way... how to do unit tests for this pipeline validation behavior?

  • @balakrishnang5603
    @balakrishnang5603 Před 3 lety

    good job

  • @avanthasiriwardana
    @avanthasiriwardana Před 2 lety

    Subscribed pal :)

  • @ankitnagpal5733
    @ankitnagpal5733 Před 2 lety

    Thanks for the video.
    How does multiple behaviours share data in MediatR?

  • @LemmensSteven
    @LemmensSteven Před 4 lety

    Great video. Thanks for the explanation. What tool do you use to draw on the screen like that?

  • @S4UR4BH4
    @S4UR4BH4 Před rokem

    Just one question, does adding this transient service of pipeline behavior cause significant load w.r.t to performance or it more or less same? or to be simple does this overall process of validation impact performance of the microservice?

  • @SajadJalilian
    @SajadJalilian Před 2 lety +2

    If you have a playlist, please add it you your video descriptions. It's always hard for me to find a playlist which video is in it

  • @HarjinderSingh-df7bs
    @HarjinderSingh-df7bs Před rokem

    Hey Nick, Thanks for the great video.
    10:45 I am unable to implement this. I have searched the internet and everyone is throwing exceptions.
    Could you please share an example of this.
    Thanks in advance.

  • @adhivenkatesh3431
    @adhivenkatesh3431 Před 3 lety

    Hi your videos are awesome , may I know the editor your using for the dotnet core

    •  Před 3 lety

      Rider from JetBrains

    • @adhivenkatesh3431
      @adhivenkatesh3431 Před 3 lety

      @ , thanks for your reply , just found a link for the comparison www.jetbrains.com/rider/compare/rider-vs-visual-studio/

  • @AndrewRoberts42
    @AndrewRoberts42 Před 4 lety

    Hi Nick, How would you do FluentValidation for a PUT request where you may have a [FromRoute] int CustomerId, [FromRoute] int ProductId and [FromBody] UpdateCustomerOrderCommand in the Controller.

    • @nickchapsas
      @nickchapsas  Před 4 lety +3

      I would wrapp all 3 of those things in a UpdateCustomerOrderRequest, which contains all those properties with their attributes and create an AbstractValidator. Then you can simply validate on that.

    • @AndrewRoberts42
      @AndrewRoberts42 Před 4 lety

      @@nickchapsas
      Does it look like this? End up with multiple classes (the Command and the wrapped class) inheriting from IRequest
      Bit confused about the use of a Command object in this scenario where the Command represents the body but the domain logic also needs the Route/Query params
      Should the UpdateCustomerOrderRequest become the Command object?
      (is this the best place to ask code questions?)
      public class UpdateCustomerOrderRequest: IRequest
      //should this be the Command object?
      {
      [FromRoute]
      internal Guid OrderId { get; set; }
      [FromBody]
      internal UpdateCustomerOrderCommand Command { get; set; }
      //should this be a POCO?
      }
      public class UpdateCustomerOrderCommand : IRequest
      {
      public Guid CustomerId { get; set; }
      public Guid ProductId { get; set; }
      }
      [HttpPut("{orderId}")]
      public async Task UpdateOrder(UpdateCustomerOrderRequest request)
      {
      await _mediator.Send(request);
      return Ok();
      }

  • @starktony1587
    @starktony1587 Před 3 lety +1

    How to do unit testing for this?

  • @Fred-yq3fs
    @Fred-yq3fs Před 3 lety +1

    At around 10:45: Instead of throwing exceptions from validation, return a Result
    Then in the pipeline translate it to a BadRequest, etc...
    Which pipeline? An action filter in the API I guess?

  • @cicerofoscarini8890
    @cicerofoscarini8890 Před 2 lety

    Hi Thank you very much for the video. I have two questions: which IDE are you using and I could not find a code on github. I'm not sure which repository to clone. Could you share it here, please? Thank you very much.

    • @herve952
      @herve952 Před rokem

      He's using Jetbrains' Rider IDE

  • @temp50
    @temp50 Před 3 lety

    And is it a good thing to let the raw request data to hit the action method? Every developer in the team should be aware of this behavior, otherwise one could think that the request data has already been validated.

  • @bonaoenchelcha
    @bonaoenchelcha Před 2 lety

    Ok, let say that I'm not going to use Exception Handler, what can be a real alternative in order to say something went wrong?

  • @johanwiersma2242
    @johanwiersma2242 Před 4 lety

    Trying your sample using asp.net core 3.1, but i can't find the services.AddValidatorsFromAssembly() function?

    • @ganirban82
      @ganirban82 Před 4 lety

      chg it to dotnetcore 3.0

    • @AscottDev
      @AscottDev Před 4 lety

      I use services.AddValidatorsFromAssembly(Assembly.Load("full.assembly.name"));

  • @chiragpatel4601
    @chiragpatel4601 Před 2 lety +1

    how to adjust pipeline Behavior sequence. for ex. request-> Validate-> Cache-> Response and request->Cache->Validate->Response.

    • @nexaroth
      @nexaroth Před rokem

      I need an answer on this question as well!

  • @asitkumarmohanty2579
    @asitkumarmohanty2579 Před 4 lety

    I couldn't able to find the source code on your website. Can you please provide. Thanks in advance.

  • @TheEamonKeane
    @TheEamonKeane Před 3 lety

    Hi Nick, do you have any video on testing the fluent validation? Would you just use some integration tests?

    • @nickchapsas
      @nickchapsas  Před 3 lety +1

      I would use unit tests and integration tests

  • @pedroferreira9234
    @pedroferreira9234 Před 3 lety

    I think creating a request object just to map to a command is unnecessary (4:35), since the command is already disconnected from the model. What is the advantage by creating a request object in this case?

    • @nickchapsas
      @nickchapsas  Před 3 lety +1

      The advantage is that there is a clear separation between your API layer and your domain layer. I you pass the same object then your API and your domain are coupled and you are risking making breaking changes on the API level.

    • @pedroferreira9234
      @pedroferreira9234 Před 3 lety

      @@nickchapsas In my project i pass to the API a "CreateValueCommand" that is different from my domain model "Value". Are you using the CreateCustomerOrderCommand as a Domain model in this video?

    • @nickchapsas
      @nickchapsas  Před 3 lety +1

      That’s correct

    • @pedroferreira9234
      @pedroferreira9234 Před 3 lety

      @@nickchapsas appreciated, thank you

  • @somnathroy4875
    @somnathroy4875 Před 2 lety

    Are these codes still available in github? I looked for it but couldn't find it. Really loved the videos.

    • @nickchapsas
      @nickchapsas  Před 2 lety

      Hello Somnath. The code is available to my Patreons

  • @darkogele
    @darkogele Před 2 lety

    Do you have the code from this somewhere Nick? And can i have the link if u got it :)

    • @nickchapsas
      @nickchapsas  Před 2 lety

      The code for all my videos is available to my Patreons

  • @dfytq
    @dfytq Před 2 lety

    By default mediatr.send method runs in synchronous way. How to configure it so that it works on asynchronous way?

    • @nickchapsas
      @nickchapsas  Před 2 lety +1

      It doesn't. The synchronous way has actually been completely removed for a long time now.

    • @dfytq
      @dfytq Před 2 lety

      @@nickchapsas I didn't know that. Thanks. Is it possible to setup multiple handler for a single command?
      And is it possible to setup multiple handler for single iNotification? Will both handler be executed same time?

    • @nickchapsas
      @nickchapsas  Před 2 lety +1

      @@dfytq Yes you can. Notifications is a one to many relationships and all notification handlers will run when a notification is sent

  • @v.kozenko
    @v.kozenko Před 3 lety

    hi, what do u think about using ActionFilter instead MediatR?

    • @v.kozenko
      @v.kozenko Před 3 lety

      public class ValidationFilter : IAsyncActionFilter
      {
      public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
      {
      if (!context.ModelState.IsValid)
      {
      var modelstateErrors = context.ModelState.Where(x => x.Value.Errors.Count > 0)
      .ToDictionary(k => k.Key, v => v.Value.Errors.Select(x => x.ErrorMessage).ToArray());
      var validationResponse = new ValidationResponse();
      validationResponse.GlobalValidationMessage = "Invalid form value";
      foreach (var error in modelstateErrors)
      {
      foreach (var message in error.Value)
      {
      validationResponse.ValidationErrors.Add(new ValidationErrorModel
      {
      FieldName = error.Key,
      Message = message
      });
      }
      }
      context.Result = new BadRequestObjectResult(validationResponse);
      return;
      }
      await next();
      }
      }

  • @clearlyunwell
    @clearlyunwell Před 3 lety

    👍🏽

  • @hanspetervollhorst1
    @hanspetervollhorst1 Před 2 lety

    Isn't it a bit nit-picky to consider the performance impact of one throw-catch per request in the context of network communication?

    • @nickchapsas
      @nickchapsas  Před 2 lety

      Depends on your performance requirements

    • @hanspetervollhorst1
      @hanspetervollhorst1 Před 2 lety +1

      @@nickchapsas Can you make a course/ video on Validation, especially focussing on which responsibility lies in which levels of validation (Domain, Api)? I checked your video on CleanArchitecture and ValueObjects but I am a bit befuddled by that topic now. Thank you for reading :-)

  • @reachvkvlogs
    @reachvkvlogs Před 4 lety +1

    Great video but I can't access the source code either on github

  • @F2H16
    @F2H16 Před 3 lety

    Where can I get the source code ? Could you please help me to find the source code?

    • @nickchapsas
      @nickchapsas  Před 3 lety +1

      The source code is available by becoming a Patreon member

  • @johnnybravohonk6964
    @johnnybravohonk6964 Před 3 lety

    I think the video would benefit from a word of explanation why would we use this instead of ASP.NET middlewares - just to avoid people jumping into MediatR to get this feature, not realizing this pattern is already available.

    • @nickchapsas
      @nickchapsas  Před 3 lety

      I think I mention that in the video but that was a while ago so I could be wrong. Middleware will validate your API level model. You shouldn’t really use them for domain related concerns. Middleware should catch things related to the api request for example “this field is missing from the body or this should be a string”. Pipelines sea with the domain model and validate domain related concerns. In reality you need both.

    • @corruptmind7
      @corruptmind7 Před 3 lety

      @@nickchapsas Thanks for the videos they are awesome, I am little confused on this video, Should domain level cross cutting concerns reside in domain layer or at application layer ?Domain layer exceptions (not errors) can be handled by giving a proper messge to consumer (Bad Request), however for application level or persistance level errors i want to handle in a different way(let;s say common error message and logging ), Should'nt a business level dependency be a part of the domain layer ?

    • @DaveRogersEsq
      @DaveRogersEsq Před 2 lety

      Why would you use middlewares? You would end up adding loads of Middlewares for all kinds of domain-centric scenarios for every single request. So, for any one request, almost all of those middlewares would not be relevant. This is not a good approach if you care about performance. (This is not a good approach anyway 😁)

  • @patrickhitch
    @patrickhitch Před 2 lety

    Is it just me or did I miss where you are translating that validation exception into a response? There is nothing in your controller to handle that exception! And no attribute on the action method either

  • @mmsky6316
    @mmsky6316 Před 4 lety

    Great video but I can't access the source code either on github (I also subscribed to the mailing list)

    • @nickchapsas
      @nickchapsas  Před 4 lety

      Please send me your GitHub username and I will manually invite you

    • @mmsky
      @mmsky Před 4 lety

      @@nickchapsas I spoke too soon. I was able to access it! Thank you!

  • @sohamde
    @sohamde Před rokem +1

    Please read this ! Or pin this
    In Validation Behavior.cs file
    Change the
    Var context = new ValidationContext(request) ❎❎❎❌
    To
    Var context = new ValidationContext(request). ✔️✔️✔️
    And also remove the using validation context at line 8.
    This is because fluent api change

  • @rainron2664
    @rainron2664 Před rokem

    Sir want to clear up some confusion, what is the diff. between IPostHandler and IPipelineBehavior? thank you.😊

  • @dariogriffo
    @dariogriffo Před 3 lety

    No need to use a behaviour. A Preprocessor is more suitable for this.

  • @codematrix
    @codematrix Před 3 lety +2

    Too much abstraction. This will be difficult to debug as you can’t drill down from the mediatR to the final handler and need to manually search for the handlers. Sounds cool and is decoupled, but the over use of design patterns everywhere increases architectural complexity. In other words don’t over engineer because you found a new tool. Always have a good balance. You don’t need this for CQRS. Use straight DI. Also meditatR makes it difficult to inject fakes during unit testing.

    • @nickchapsas
      @nickchapsas  Před 3 lety +4

      MediatR makes it very easy to inject fakes during unit testing.