我构建了一个自定义ValidationAttribute,因此我可以在系统中验证唯一的电子邮件地址。但是,我想以某种方式传入自定义参数,以便为我的验证添加更多逻辑。
public class UniqueEmailAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
//I need the original value here so I won't validate if it hasn't changed.
return value != null && Validation.IsEmailUnique(value.ToString());
}
}
答案 0 :(得分:32)
喜欢这个吗?
public class StringLengthValidatorNullable : ValidationAttribute
{
public int MinStringLength { get; set; }
public int MaxStringLength { get; set; }
public override bool IsValid(object value)
{
if (value == null)
{
return false;
}
var length = value.ToString().Length;
if (length < MinStringLength || length >= MaxStringLength)
{
return false;
}
return true;
}
}
使用:
[StringLengthValidatorNullable(MinStringLength = 1, MaxStringLength = 16)]
public string Name {get; set;}
答案 1 :(得分:1)
有一个类似的要求,我必须将值传递给自定义属性。
这里的问题是属性装饰不允许变量。 你得到编译时错误:
非静态字段,方法或者需要对象引用 属性
以下是我能够做到的事情:
在控制器中
[FineGrainAuthorization]
public class SomeABCController : Controller
{
public int SomeId { get { return 1; } }
}
在属性中
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class FineGrainAuthorizationAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
ControllerBase callingController = filterContext.Controller;
var someIdProperty = callingController.GetType().GetProperties().Where(t => t.Name.Equals("SomeId")).First();
int someId = (int) someIdProperty.GetValue(callingController, null);
}
}
请记住,.Name.Equals("SomeId")
中的字符串必须与声明public int SomeId
答案 2 :(得分:1)
您还可以传递同一模型中其他属性的参数。
创建自定义验证属性:
public class SomeValidationAttribute : ValidationAttribute
{
//A property to hold the name of the one you're going to use.
public string OtherProperty { get; set; }
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
//Get the value of the property using reflection.
var otherProperty = validationContext.ObjectType.GetProperty(OtherProperty);
var otherPropertyValue = (bool)otherProperty.GetValue(validationContext.ObjectInstance, null);
if (value != null && otherPropertyValue)
{
return ValidationResult.Success;
}
return new ValidationResult("Invalid property message.");
}
}
然后传递您将要使用的属性的名称。
public class RequestModel
{
public bool SomeProperty { get; set; }
[SomeValidation(OtherProperty = "SomeProperty")]
public DateTime? StartDate { get; set; }
}
答案 3 :(得分:0)
我会建议类似@Oliver的答案(不管怎么说,这就是我要做的),但后来我注意到你不想传递常数。
那么这样的事情呢?
public static class MyConfig
{
public static int MinStringLength { get; set; }
public static int MaxStringLength { get; set; }
public static SomeObject otherConfigObject { get; set; }
}
然后从验证中访问MyConfig.MinStringLength
?
不过,我会同意它不太漂亮。