关于c#:在代码中的StringLengthAttribute上设置MaximumLength

Setting MaximumLength on a StringLengthAttribute in code

我正在处理一些代码,这些代码在视图模型上使用DataAnnotation属性,并在某些情况下以编程方式覆盖某些属性。

在各种类型的ValidationAttributes上更改ErrorMessage,没问题。

DataFormatString更改为DisplayFormatAttributes,没问题。

MinimumLength更改为StringLengthAttribute,没问题。但是.. MaximumLength没有公共设置器!?

在周围都是公共场所时,有什么理由使这处房产脱颖而出?我可以通过编程方式更改StringLengthAttribute的最大长度吗?


由于设置MaximumLength属性的唯一公共方法是通过属性构造函数,因此没有编程方式可以在构造后更改它。假设您以足够的信任度运行代码,则始终可以使用私有反射来执行所需的操作。如果您不想(或不能)走那条路线,另一种选择是在给定条件下交换视图模型,而不仅仅是根据需要更新属性。然后,您可以为每个单独的视图模型构造所需的属性,而不必担心通过编程方式更改属性本身。

最后一个选择是实际编写您自己的StringLength属性。您可以轻松地模拟内置版本的功能,因为其IsValid()方法非常简单:

1
2
3
4
5
public override bool IsValid(object value)
{
    int num = (value == null) ? 0 : ((string)value).Length;
    return value == null || (num >= this.MinimumLength && num <= this.MaximumLength);
}

模仿这一点,但在MaximumLength属性上包含一个public设置器,即可满足您的需求。


假设您正在使用自定义ModelMetadataValidatorProvider,如我在MVC3中如何在TemplateEditor中向模型属性添加验证属性中概述的那样,在重写GetValidators方法的过程中,可以遍历基本方法返回的验证器,然后删除当前的StringLengthAttribute,并用所需的MaxLength值替换您的StringLengthAttribute。


由于此代码是特定于ViewModel的,因此请让您的ViewModel实现IValidateableObject接口并在其中进行验证。

1
2
3
4
5
6
7
8
9
<wyn>
public IEnumerable Validate(ValidationContext validationContext)
{
    if (YourField.Length == 2)
    {
        yield return new ValidationResult("ut oh!!");
    }
}
</wyn>