question

DmitriyReznik-4665 avatar image
0 Votes"
DmitriyReznik-4665 asked DmitriyReznik-4665 answered

Blazor: Validation doesn't work on a derived model

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?

dotnet-aspnet-core-blazor
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

AgaveJoe avatar image
0 Votes"
AgaveJoe answered AgaveJoe edited

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.



· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

@AgaveJoe Thank you for your answer. Could you please tell how I can send the excepted type, or refer me to where I can read about it?

0 Votes 0 ·
DmitriyReznik-4665 avatar image
0 Votes"
DmitriyReznik-4665 answered

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...

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.