1

我正在尝试为我的 MVC 应用程序创建自定义验证属性。我编写的代码非常适合代码中指定的属性。我现在想扩展它,所以它更通用,因为我有 5 个其他属性我想使用这个相同的属性。
一般的想法是如果指定的其他属性为真,那么附加到属性的属性必须> 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)
    //{

    //}

}

谢谢你的时间。

4

1 回答 1

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+ RCtrl+R来重命名变量,它也会自动重命名 nameof 中的版本。惊人的!

See: nameof (C# and Visual Basic Reference)

于 2012-11-07T16:08:53.113 回答