Search code examples
c#nhibernatefluentvalidation

Validate inherited classes using FluentValidation | C# Web API


I want to create a validation for my c# web api. In my first question you can see my models: Click here

Now I created the following validators:

public class AnimalValidator<T> : AbstractValidator<T> where T : Animal
{
    private ISessionService sessionService;

    public AnimalValidator(ISessionService sessionService)
    {
         this.sessionService = sessionService;

         RuleSet("Create", () =>
         {
             // some validation
         });

         RuleSet("Edit", () =>
         {
             // some validation
         });
     }
 }

and...

public class DogValidator : AnimalValidator<Dog>
{
   private ISessionService sessionService;

   public DogValidator(ISessionService sessionService) // Error: There is no argument given that corresponds to the required formal parameter 'sessionService'
   {
       this.sessionService = sessionService;

       RuleSet("Create", () =>
       {
           // some validation
       });

       RuleSet("Edit", () =>
       {
           // some validation
       });
    }
  }

and...

public class CatValidator : AnimalValidator<Cat>
{
   private ISessionService sessionService;

   public CatValidator(ISessionService sessionService) // Error: There is no argument given that corresponds to the required formal parameter 'sessionService'
   {
       this.sessionService = sessionService;

       RuleSet("Create", () =>
       {
           // some validation
       });

       RuleSet("Edit", () =>
       {
           // some validation
       });
   }
 }

In my first question as mentioned above I have made the code as in the answer.

I try to call the validation like this:

if (validationService.IsValid(animal, ruleSetNames: new List<string>() { 
"Create" }, propertyNames: null))
{ // do stuff here }

The problem is, that animal is of type object.

Need your help. How can I get rid of the validator errors and how can I call the validation properly?

Thanks in advance.

EDIT:

How do I have to register my validator in the ValidationFactory? Currently I have:

validators.Add(typeof(IValidator<Animal>), new ValidationFactoryItem(typeof(AnimalValidator), new object[] { sessionService }));
validators.Add(typeof(IValidator<Dog>), new ValidationFactoryItem(typeof(DogValidator), new object[] { sessionService }));
validators.Add(typeof(IValidator<Cat>), new ValidationFactoryItem(typeof(CatValidator), new object[] { sessionService }));

I always get the error:

System.InvalidOperationException: 'No validator registered for the given type.'

It seems the type is object but it should be either dog or cat...

Please help me. :)


Solution

  • Did you mean the classes to be called DogValidator and CatValidator? Because your constructors refer to that but your classes are called Dog and Cat.

    When your base class doesn't have an empty contructor you need to pass constructor parameters to it from your subclass using ": base(" syntax, i.e. I think DogValidator should look something like this:

    public class DogValidator : AnimalValidator<Dog>
    {
       private ISessionService sessionService;
    
       public DogValidator(ISessionService sessionService) : base(sessionService)
       {
           this.sessionService = sessionService;
    
           RuleSet("Create", () =>
           {
               // some validation
           });
    
           RuleSet("Edit", () =>
           {
               // some validation
           });
        }
      }  
    

    Note that you're currently also storing sessionService twice in both DogValidator and AnimalValidator, but fixing the class name and adding the base class constructor call should sort out your compile issue.