这有两个部分。首先,您必须编写一个仅当其他属性符合您的条件时才需要的必需属性。
您必须执行以下操作:
public class RequiredComparerAttribute : RequiredAttribute
{
public OtherProperty { get; set; }
public override bool IsValid(object value)
{
// TODO: use reflection to validate other property as PropertyInfo
// or validate it's value after it is decided to be valid
foreach (ValidationAttribute va in property
.GetCustomAttributes(typeof(ValidationAttribute), true)
.OfType<ValidationAttribute>())
{
if (!va.IsValid(value))
{
return false; // not required
}
}
return true; // required
}
}
然后,在 Global.asax 的 Application_Start 中,您必须注册验证器,您可以重复使用 RequiredAttribute 的验证器:
DataAnnotationsModelValidatorProvider
.RegisterAdapter(typeof(RequiredComparerAttribute),
typeof(RequiredAttributeAdapter));
如果您想添加自己的验证器,则必须编写自定义验证器。 Phil Haack 在他的博客上有一个例子:http://haacked.com/archive/2009/11/19/aspnetmvc2-custom-validation.aspx
编辑:查看 .NET Reflector 中的 CompareAttribute,了解如何获取 OtherProperty 的值。 CompareAttribute 还实现了IClientValidatable 以提供客户端所需的那些验证规则。
我不认为 CompareAttribute 对您有用,因为您必须根据另一个属性的内容验证是否需要一个值,而不是比较两个属性的相等性。
Edit2:验证提供者做什么?
它将规则添加到表单并为这些规则提供消息。通过下载 MVC 3 源代码,您可以准确了解 RequiredAttributeAdapter 是如何做到这一点的。要了解它在客户端的作用,您可以在 Google Chrome 中打开 MVC 3 页面,按 CTRL+SHIFT+J 调出开发人员工具窗口并输入:
$('form:first').data().unobtrusiveValidation.options
options 中的 rules 对象指定如何验证每个项目,message 对象指定将针对每个验证错误显示的错误消息。
Edit3:完整示例
自从回答了这个问题后,我写了一篇博文,其中包含在客户端(不显眼的验证)和服务器上创建自定义属性的完整示例。博文是here。此示例适用于“包含”属性,但应该很容易修改以成为必需的比较。