Blazor: Validation doesn't work on a derived model

Dmitriy Reznik 236 Reputation points
2022-06-23T13:01:37.647+00:00

I have a Blazor server-side application. I have two viewmodel classes, and one of them is derived from another:

public class QuoteModel : IValidatableObject  
{  
    ...  
  
    public virtual IEnumerable<ValidationResult> Validate(ValidationContext validationContext)  
    {  
        var result = new List<ValidationResult>();  
  
        if (StatusId >= (int)Models.Status.VendorReview)   
        {  
            if (UnitPrice == 0)  
            {  
                result.Add(new ValidationResult("Unit Price is required."));  
            }  
            else if (UnitPrice < 0)  
            {  
                result.Add(new ValidationResult("Unit Price must be greater than 0."));  
            }  
        }  
        ...  
  
        return result;  
    }  
}  
  
public class LinearDrainGrateQuoteModel : QuoteModel  
{  
    public override IEnumerable<ValidationResult> Validate(ValidationContext validationContext)  
    {  
        List<ValidationResult> result = (List<ValidationResult>)base.Validate(validationContext);  
  
        if (OutletId == null)  
        {  
            result.Add(new ValidationResult("Outlet Type is required."));  
        }  
  
        return result;  
    }  
}  

For some reason the Validate() method of the derived class is not called. When I use a base QuoteModel object, the base class Validate() is called as expected. What am I missing?

Blazor
Blazor
A free and open-source web framework that enables developers to create web apps using C# and HTML being developed by Microsoft.
1,386 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. AgaveJoe 26,201 Reputation points
    2022-06-23T13:44:14.3+00:00

    For some reason the Validate() method of the derived class is not called. When I use a base QuoteModel object, the base class Validate() is called as expected. What am I missing?

    Blazor server uses SignalR (web socket) to send serialized messages back and forth. If the receiving method defines a base class input parameter then the base class is instantiated not the derived class.

    In order to pass inheritance over the wire you have to send more information like the excepted type so the receiver knows how to instantiate the type. Essentially design/create custom model binding.


  2. Dmitriy Reznik 236 Reputation points
    2022-06-23T14:54:59.86+00:00

    I found the explanation here:

    https://gist.github.com/ncarandini/b0839175ce8c40c2b38605bb62844cbc

    When using Blazor form validation with a model class that implement IValidatableObject, the overloaded Validate method is called only on form submit and only if no other validation decorated properties fails.

    So it had nothing to do with inheritance...

    0 comments No comments