Question

I am trying to override a DataAnnotation in the child class.

I have tried solutions by similar questions but I had limited success.

For example I have this class using the RangeAttribute

public class BaseViewModel 
{
    [Range(1, 99999999, ErrorMessageResourceName = "NotInRange9M", ErrorMessageResourceType = typeof(Resources.Account))]
    public virtual decimal? Amount { get; set; }
}

and a child class:

public class ExtendedViewModel : BaseViewModel
{
    internal decimal? _amount;

    [Range(1, 2000, ErrorMessageResourceName = "NotInRange2K", ErrorMessageResourceType = typeof(Resources.Account))]
    public override decimal? Amount {
        get { return _amount; }
        set { _amount = value; }
    }
}

This example works, so the form with that uses the first object will give a client side validation error "The amount must be between 1 and 999,999,999" and the second one will say "The amount must be between 1 and 2,000".

However if I want to have the child class without any validation at all:

public class ExtendedViewModel : BaseViewModel
{
    internal decimal? _amount;

    public override decimal? Amount {
        get { return _amount; }
        set { _amount = value; }
    }
}

The form using this will still give the client side validation error "The amount must be between 1 and 999,999,999", which it somehow inherits from the parent.

So we can override attributes but we can't get rid of them? Is there another way?

I have also tried:

    new public decimal? Amount {
        get { return _amount; }
        set { _amount = value; }
    }

without success.

I had to work around this limitation but I want to understand this mechanism of Data Annotations so I can use them better.

Was it helpful?

Solution

Well, there's an AttributeUsageAttribute... on Attributes classes.

For example, RangeAttribute looks like that

[AttributeUsage(AttributeTargets.Property|AttributeTargets.Field|AttributeTargets.Parameter, AllowMultiple = false)]
public class RangeAttribute : ValidationAttribute

One of the properties of AttributeUsageAttribute class is Inherited, which looks like that.

    //
    // Summary:
    //     Gets or sets a Boolean value indicating whether the indicated attribute can
    //     be inherited by derived classes and overriding members.
    //
    // Returns:
    //     true if the attribute can be inherited by derived classes and overriding
    //     members; otherwise, false. The default is true.
    public bool Inherited { get; set; }

So as we've seen in Definition of RangeAttribute, Inherited property is not present in attribute. So by default it's true, so attribute is inherited on overriding members.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top