自定义验证类 - 如何使通用

时间:2012-10-24 21:02:27

标签: c# asp.net-mvc validation

我正在尝试为我的MVC应用程序创建自定义验证属性。我编写的代码非常适合代码中指定的属性。我现在想扩展它,所以它更通用,因为我有5个其他属性我想使用这个相同的属性。
一般的想法是,如果指定的其他属性为true,则附加到该属性的属性必须是> 0

我假设这样做的方法是创建一个构造函数来接受属性的值和另一个属性的值,但我似乎无法理解它。我遇到的具体问题是我无法找到正确的方法来获取所需的值。

这就是我所拥有的:

public class MustBeGreaterIfTrueAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext context)
    {
        var model = context.ObjectInstance as HistoryViewModel;
        //ValidationResult result = null;

        // Validate to ensure the model is the correct one
        if (context.ObjectInstance.GetType().Name == null)
        {
            throw new InvalidOperationException(string.Format(
                    CultureInfo.InvariantCulture, "Context of type {0} is not supported. "
                                                  + "Expected type HistoryViewModel",
                                                   context.ObjectInstance.GetType().Name));
        }

        // Here is the actual custom rule
        if (model.HistoryModel.IsRetired == true)
        {
            if (model.CounterA == 0)
            {
                return new ValidationResult("Please enter more information regarding your History");
            }
        }
        else if ( model.HistoryModel.IsRetired == true )
        {
            if ( model.ROCounter > 0 )

            return ValidationResult.Success;
        }

        // If all is ok, return successful.
        return ValidationResult.Success;

    }

    //  Add the client side unobtrusive 'data-val' attributes
    //public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    //{

    //}

}

谢谢你的时间。

1 个答案:

答案 0 :(得分:1)

我刚刚在一个名为“RequiredIfTrueAttribute”的属性中做了类似的事情。这将获得模型中其他属性的值。将其他属性名称作为字符串传递给自定义属性构造函数。

public class RequiredIfTrueAttribute: ValidationAttributeBase
{

    public string DependentPropertyName { get; private set; }

    public RequiredIfTrueAttribute(string dependentPropertyName) 
        : base()
    {
            this.DependentPropertyName = dependentPropertyName;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        // Get the property we need to see if we need to perform validation
        PropertyInfo property = validationContext.ObjectType.GetProperty(this.DependentPropertyName);
        object propertyValue = property.GetValue(validationContext.ObjectInstance, null);

        // ... logic specific to my attribute

        return ValidationResult.Success;
    }


}

现在,如果只有一种方法可以将dependentPropertyName传递给验证属性而不使用字符串......


更新

在C#6.0中,现在有一种方法可以在不使用字符串的情况下调用dependentPropertyName。只需使用nameof(thePropertyName),它就会被字符串替换。这在编译时发生,因此如果您更改属性名称,您将立即知道您还需要更改它。或者,更好的是,如果您执行 Ctrl + R Ctrl + R 重命名变量,它将自动重命名nameof中的版本。真棒!

请参阅:nameof (C# and Visual Basic Reference)