简体   繁体   中英

Why do inherited data annotations stop working?

If someone misses the tags: I'm using .NET MVC5 to develop a web application, and using data annotations for validation (both client and server side).

I wanted to customise the built in annotations (Required, StringLentgth, Range etc.) to suit my needs a little better. I started by making my own class that inherits RequiredAttribute , added literally nothing, and replaced Required on my viewmodel with Test . I ran that, expecting it to work 100% like it did before, but to my surprise, the validation stopped working completely for the said field. In HTML, the data-val-required="......" that was there previously, simply didn't show up any more.

My new attribute (I've tried it with or without usage specification, result is the same):

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
public class TestAttribute : RequiredAttribute
{
    // Literally nothing new, same as superclass.
}

The annotated property in viewmodel:

// Before, works.
[Required]
public int WorkerId { get; set; }

// After, doesn't work.
[Test]
public int WorkerId { get; set; }

So, how does this work? How come the behavior changes simply by subclassing? How should I inherit attributes to inherit their behaviour? Isn't this a violation of Liskov substitution principle?

Well I'd expect server side validation to continue to work but the reason client-side validation stops working is that you have to tell ASP.NET which adapter to use to generate the client-side validation JavaScript. If you're not actually changing the behaviour of RequiredAttribute you could just use its adapter. Put the below code in your Application_Start() method.

DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(Test), typeof(RequiredAttributeAdapter));

[Update : AS Davor pointed out in comment. It is a WRONG!! answer. Just leaving this for anyone come across the same. Sorry. ]

The Required attribute referenced in MSDN as a non-inheritable. https://msdn.microsoft.com/en-us/library/microsoft.build.framework.requiredattribute(v=vs.110).aspx

  [AttributeUsageAttribute(AttributeTargets.Property, AllowMultiple = false, Inherited = false)] public sealed class RequiredAttribute : Attribute 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM