我尝试了 Mahmoud 的答案,但如果没有一些更改,它对我不起作用。将此添加为答案,以便我可以提供代码以防万一它对其他人有所帮助,但完全归功于 Mahmoud Hboubati - 我已赞成您的答案。
在我的情况下,我有一个带有 DbGeography 属性的基本 DTO 类,这是 MVC 项目所需的,该项目使用自定义 EditorTemplate 和 DisplayTemplate 作为 DbGeography 类型。但是为了将模型发布到 Web API 控制器,我希望将纬度/经度字段添加到该 DTO 的子类中,这将用于创建和设置 DbGeography 类的实例以设置 DbGeography 属性的值。问题是,我无法使 DbGeography 属性仅在子类中不需要。
当使用 Mahmoud 的方法在构造函数中传递布尔值时,它似乎从未覆盖我的默认值。这可能是因为我正在使用 Web API 并使用工厂方法注册属性,如下所示(在 Global.asax.cs Application_Start 方法中):
DataAnnotationsModelValidationFactory factory = (p, a) => new DataAnnotationsModelValidator(
new List<ModelValidatorProvider>(), new RequiredExAttribute()
);
DataAnnotationsModelValidatorProvider provider = new DataAnnotationsModelValidatorProvider();
provider.RegisterAdapterFactory(typeof(RequiredExAttribute), factory);
我不得不把属性类改成这样:
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
...
public class RequiredExAttribute : RequiredAttribute
{
public bool IsRequired { get; set; }
public override bool IsValid(object value)
{
if (IsRequired)
return base.IsValid(value);
else
{
return true;
}
}
public override bool RequiresValidationContext
{
get
{
return IsRequired;
}
}
}
public class RequiredExAttributeAdapter : RequiredAttributeAdapter
{
public RequiredExAttributeAdapter(ModelMetadata metadata, ControllerContext context, RequiredExAttribute attribute)
: base(metadata, context, attribute) { }
public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
{
if (((RequiredExAttribute)Attribute).IsRequired)// required -> return normal required rules
return base.GetClientValidationRules();
else// not required -> return empty rules list
return new List<ModelClientValidationRule>();
}
}
基类:
[RequiredEx(IsRequired = true)]
public virtual DbGeography Location { get; set; }
子类:
[RequiredEx(IsRequired = false)]
public override DbGeography Location { get; set; }
[Required]
public decimal Latitude { get; set; }
[Required]
public decimal Longitude { get; set; }
注意,我使用与 Mahmoud 上面相同的方法在我的 MVC 项目中注册属性:
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(RequiredExAttribute), typeof(RequiredExAttributeAdapter));