Asp.net mvc ASP.NET MVC ValidationAttribute获取其他属性显示名称

Asp.net mvc ASP.NET MVC ValidationAttribute获取其他属性显示名称,asp.net-mvc,validation,client-side-validation,validationattribute,Asp.net Mvc,Validation,Client Side Validation,Validationattribute,通过复制ASP.NET MVC 3 CompareAttribute,我创建了一个自定义的CompareLessThan验证属性,我没有检查相等性,而是检查一个属性是否小于另一个属性。如果存在客户端错误,则向用户显示消息“{0}必须小于{1}” 我的模型设置如下,显示属性引用资源文件 [CompareLessThan("AmountAvailable", ErrorMessageResourceName="CompareLessThan", ErrorMessageResourceType =

通过复制ASP.NET MVC 3 CompareAttribute,我创建了一个自定义的CompareLessThan验证属性,我没有检查相等性,而是检查一个属性是否小于另一个属性。如果存在客户端错误,则向用户显示消息“{0}必须小于{1}”

我的模型设置如下,显示属性引用资源文件

[CompareLessThan("AmountAvailable", ErrorMessageResourceName="CompareLessThan", ErrorMessageResourceType = typeof(Resources.ValidationMessages))]
[Display(Name = "Amount", ResourceType = typeof(Resources.Labels))]
public decimal Amount { get; set; }

[Display(Name = "AmountAvailable", ResourceType = typeof(Resources.Labels))]
public decimal AmountAvailable { get; set; }
然后,自定义验证GetClientValidationRules方法与CompareAttribute中的方法完全相同

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{            
    yield return new ModelClientValidationLessThanRule(FormatErrorMessage(metadata.DisplayName), FormatPropertyForClientValidation(OtherProperty), this.AllowEquality);
}
public IEnumerable GetClientValidationRules(ModelMetadata元数据,ControllerContext上下文)
{            
返回新的ModelClientValidationLessThanRule(FormatErrorMessage(metadata.DisplayName)、FormatPropertyForClient验证(OtherProperty)、this.AllowEquality);
}
这里我们将生成一条错误消息,如果出现问题,将向用户显示该消息。我可以从资源文件中获取使用自定义CompareLessThan属性修饰的属性的显示名称,但我的问题是如何获取我们要比较的“其他”属性的显示名称?在IsValid方法中,我们有一个对validationContext的引用,从中我可以为'other'属性生成PropertyInfo对象,我想可以得到显示名称。但是,在GetClientValidationRules中,我没有访问权限

我总是可以为另一个属性的显示名传入另一个值,但我希望有一种方法可以派生它,因为我已经用数据注释指定了它


有什么想法吗?

我还没有尝试过,但是您可以使用
元数据.properties
属性获取模型属性

metadata.Properties.Single(p => p.PropertyName == "OtherPropName").DisplayName;
编辑:因为属性是空的,所以你总是可以这样做(尽管它非常优雅)。您可以自己生成元数据

var provider = new DataAnnotationsModelMetadataProvider();
var otherMetaData = provider.GetMetadataForProperty(() => metaData.Model, metaData.ModelType, "OtherPropertyName");

nemesv提供的答案不能作为元数据使用。模型属性的值为0。但是,通过元数据,我们确实拥有模型的全名,因此可以创建该模型的新实例,然后从该创建实例创建新的DataAnnonationModelMetadataProvider。从那里我们可以得到另一个属性的显示名称

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
    Type type = Type.GetType(metadata.ContainerType.FullName);
    var model = Activator.CreateInstance(type);

    var provider = new DataAnnotationsModelMetadataProvider();
    var otherMetaData = provider.GetMetadataForProperty(() => model, type, this.OtherProperty);

    this.otherPropertyDisplayName = otherMetaData.DisplayName;

    yield return new ModelClientValidationLessThanRule(FormatErrorMessage(metadata.DisplayName), FormatPropertyForClientValidation(this.OtherProperty), this.AllowEquality);
}
public IEnumerable GetClientValidationRules(ModelMetadata元数据,ControllerContext上下文)
{
Type Type=Type.GetType(metadata.ContainerType.FullName);
var model=Activator.CreateInstance(类型);
var provider=新的DataAnnotationsModelMetadataProvider();
var otherMetaData=provider.GetMetadataForProperty(()=>model,type,this.OtherProperty);
this.otherPropertyDisplayName=otherMetaData.DisplayName;
返回新的ModelClientValidationLessThanRule(FormatErrorMessage(metadata.DisplayName)、FormatPropertyForClient验证(this.OtherProperty)、this.AllowEquality);
}

我真的不喜欢这个解决方案(即使它有效),因为似乎应该有更好的方法。还有其他人有其他想法吗?

从ASP.NET MVC 4开始,我就是这样获得其他属性的:

PropertyInfo otherPropertyInfo =
                  this.Metadata.ContainerType.GetProperty(attribute.DependentProperty);
var displayAttribute =
    otherPropertyInfo.GetCustomAttributes(typeof(DisplayAttribute), true).
    FirstOrDefault() as DisplayProperty;
然后我从属性中获得了
显示属性

PropertyInfo otherPropertyInfo =
                  this.Metadata.ContainerType.GetProperty(attribute.DependentProperty);
var displayAttribute =
    otherPropertyInfo.GetCustomAttributes(typeof(DisplayAttribute), true).
    FirstOrDefault() as DisplayProperty;
就你而言:

// GetName() is important to get the translated name if you're using a resource file...
this.otherPropertyDisplayName = displayAttribute.GetName();
GetName()
参考:


好主意,但是属性集合总是空的。@NickOlsen,这很悲哀。我已经用一些“变通方法”更新了我的答案。这也不适用于元数据。模型属性只是值0。根据你的逻辑,我能够想出另一种方法来做这件事(见其他答案),但我真的不喜欢它。我希望有其他人可以提供更好的方式。这是“作为DisplayProperty”还是“作为DisplayAttribute”?我的不适用于DisplayProperty,但适用于DisplayAttribute。很好的解决办法。@MVCKarl:我认为你是对的。。。也许在这里输入答案时有点混乱。我无法准确记录我当时所做的事情。:)