0

I am using asp.net core 2.2 and model validation for server side validation. Its working fine except for known types.

this is my class structure

    //Main Class

    [DataContract]    
    [KnownType(typeof(SubClass2))]    
    [KnownType(typeof(SubClass1))]    
    public partial class MainCass : Base    
    {     
    //properties comes here     
    }     

    //Sub Classes    

    [DataContract]     
    public partial class SubClass1 : MainCass    
    {    
    //properties comes here    
    }    

    [DataContract]    
    public partial class SubClass2 : MainCass    
    {    

    [DataMember]    
    [CustomRequired(ErrorMessageResourceType = typeof(ErrorMessages),  
    ErrorMessageResourceName = "FieldRequired", Caption = "name required")]    
    public string Name  {get; set; }   

    }    

//this is my request model
    [DataContract]    
    public partial class request:Base    
    {    
    [DataMember]    
    public List<MainCass> MainCassList  {get; set; }    
    }    

now the validation attribute of Name in SubClass2 is not getting called. From UI I am sending type Subclass2.

SARATH PK
  • 13
  • 6

1 Answers1

0

The model binder does not support polymorphism. It creates the literal type(s) of the model and any related sub-models. Then, it attempts to bind the request body to these types. It will not infer derived types.

In other words, it sounds like you're sending instances of SubClass1 and SubClass2 as part of your MainClassList property. However, the model binder is going to create all of these as MainClass because that's the type that's defined. Any posted data specific to SubClass1 or SubClass2 will simply be discarded, and in the end, all you have is instances of MainClass. As such, of course no specific validation on SubClass1 or SubClass2 is being run, because you have no instances of SubClass1 or SubClass2.

Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
  • any solution to overcome this? – SARATH PK Apr 01 '19 at 13:20
  • No. It's a functional limitation of model binding. Polymorphism is a complete no-go. About the best you can do is create a view model that encompasses all derived classes so any property for any derived type can be bound, and then map over to the appropriate derived type using some sort of conditional check. – Chris Pratt Apr 01 '19 at 13:31
  • I've been stuck on this problem all day. Asp net core 3.1 correctly implements validation on derived types unless they are in a list / array. I am using the JsonSubTypes library to deserialize and I can see the correct types coming through my controller. With a single value 'subClass' controller it works but if you try to send a list of 'subClass' then it doesn't work (even though it still deserializes correctly). I feel like this is a bug, or at least an inconsistency. – Alex Horlock Aug 18 '20 at 14:42