I have a base class "BASE" and another class "RAN" which is a parent of 5 classes "RAN1", "RAN2", ..., "RAN5".
public class RAN {
}
public class RAN1 : RAN {
}
. // RAN2
. // RAN3
. // RAN4
public class RAN5 : RAN {
}
public class BASE<T> where T : RAN {
[Required]
public int Myprop {
get{...}
set{...}
}
}
I want this property "Myprop" to be "required" when T equals RAN2 or RAN4. And this property "Myprop" should be set as "not required" when T equals RAN1, RAN3, RAN5.
How do I achieve this?
CodePudding user response:
We can try to let Myprop
property be virtual
then we can try to override in RAN2
and RAN4
and add Required
attribute for that, other RANs just inherit from RAN
public class RAN {
public virtual int Myprop { get; set;}
}
public class RAN1 : RAN {
}
public class RAN2 : RAN {
[Required]
public override int Myprop { get; set;}
}
public class RAN4 : RAN {
[Required]
public override int Myprop { get; set;}
}
CodePudding user response:
You'll have to write a custom validation attribute to make something like this work. This page discusses writing custom attributes. There is also this older page that might have some relevant or useful information.
For example, you could write something like RequiredIfClassHasGenericTypeAttribute
by inheriting RequiredAttribute
and overriding the protected IsValid(object, ValidationContext
) method.
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Somenamespace
{
public class RequiredIfClassHasGenericTypeAttribute : RequiredAttribute
{
public RequiredIfClassHasGenericTypeAttribute(params Type[] requiredGenericTypes)
{
RequiredGenericTypes = requiredGenericTypes;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var instance = validationContext.ObjectInstance;
var instanceType = instance.GetType();
if (instanceType.GenericTypeArguments.Intersect(RequiredGenericTypes).Any())
{
var result = base.IsValid(value, validationContext);
return result;
}
return ValidationResult.Success;
}
private Type[] RequiredGenericTypes { get; }
}
}
Then you would use it like this...
public class BASE<T> where T : RAN
{
[RequiredIfClassHasGenericType(typeof(RAN2), typeof(RAN4))]
public int MyProp { get; set; }
}
It might also be worth mentioning that the RequiredAttribute
states in the remarks that:
The RequiredAttribute attribute specifies that when a field on a form is validated, the field must contain a value. A validation exception is raised if the property is null, contains an empty string (""), or contains only white-space characters.
An int
will never be null
, contain an empty string
, or contain only white-space characters so I'm not sure that RequiredAttribute
will ever fail for an int
.