C# MVC3自定义验证属性,用于比较有效的最小值和最大值

C# MVC3自定义验证属性,用于比较有效的最小值和最大值,c#,asp.net-mvc-3,validation,C#,Asp.net Mvc 3,Validation,我的模型有两个十进制参数,如下所示: public class Range { public decimal MinimumValue { get; set; } public decimal MaximumValue { get; set; } } 是否可以对以下两个参数进行自定义验证: 验证最小值(必须小于最大值) 验证最大值(必须大于最小值) 如果选中复选框,我为字段设置了一个自定义属性。如果未选中复选框,则该字段为必填字段;如果未选中,则该字段为非必填字段。我可以

我的模型有两个十进制参数,如下所示:

public class Range
{
     public decimal MinimumValue { get; set; }
     public decimal MaximumValue { get; set; }
}
是否可以对以下两个参数进行自定义验证:

  • 验证最小值(必须小于最大值)
  • 验证最大值(必须大于最小值)

如果选中复选框,我为字段设置了一个自定义属性。如果未选中复选框,则该字段为必填字段;如果未选中,则该字段为非必填字段。我可以使用此代码来调整和检查字段是否比其他字段大。 您还可以使用数据注释扩展。有关数据注释扩展的详细信息

公共类RequiredIf:ConditionalValidationAttribute
{
受保护的重写字符串验证名称
{
获取{return“requiredif”;}
}
public RequiredIf(字符串依赖属性,对象targetValue)
:base(新的RequiredAttribute(),dependentProperty,targetValue)
{
}
受保护的重写IDictionary GetExtraValidationParameters()
{
返回新词典
{ 
{“规则”,“必需”}
};
}
}
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property,AllowMultiple=false)]
公共抽象类ConditionalValidationAttribute:ValidationAttribute,IClientValidatable
{
受保护的只读ValidationAttribute InnerAttribute;
公共字符串依赖属性{get;set;}
公共对象TargetValue{get;set;}
受保护的抽象字符串验证名称{get;}
受保护的虚拟IDictionary GetExtraValidationParameters()
{
返回新字典();
}
受保护的条件ValidationAttribute(ValidationAttribute innerAttribute、string dependentProperty、object targetValue)
{
this.InnerAttribute=InnerAttribute;
this.DependentProperty=DependentProperty;
this.TargetValue=TargetValue;
}
受保护的重写ValidationResult有效(对象值,ValidationContext ValidationContext)
{
//获取对此验证所依赖的属性的引用
var containerType=validationContext.ObjectInstance.GetType();
var field=containerType.GetProperty(this.DependentProperty);
如果(字段!=null)
{
//获取依赖属性的值
var dependentvalue=field.GetValue(validationContext.ObjectInstance,null);
//将该值与目标值进行比较
如果((dependentvalue==null&&this.TargetValue==null)| |(dependentvalue!=null&&dependentvalue.Equals(this.TargetValue)))
{
//match=>表示我们应该尝试验证此字段
如果(!InnerAttribute.IsValid(值))
{
//验证失败-返回错误
返回新的ValidationResult(this.ErrorMessage,new[]{validationContext.MemberName});
}
}
}
返回ValidationResult.Success;
}
公共IEnumerable GetClientValidationRules(ModelMetadata元数据、ControllerContext上下文)
{
var rule=new ModelClientValidationRule()
{
ErrorMessage=FormatErrorMessage(metadata.GetDisplayName()),
ValidationType=ValidationName,
};
string depProp=BuildDependentPropertyId(元数据,上下文为ViewContext);
//找到我们所依赖的控件上的值;如果它是bool,则将其格式化为javascript样式
字符串targetValue=(this.targetValue???).ToString();
if(this.TargetValue.GetType()==typeof(bool))
{
targetValue=targetValue.ToLower();
}
rule.ValidationParameters.Add(“dependentproperty”,depProp);
规则.ValidationParameters.Add(“targetvalue”,targetvalue);
//添加额外的参数(如果有)
foreach(GetExtraValidationParameters()中的var param)
{
rule.ValidationParameters.Add(param);
}
收益率-收益率规则;
}
私有字符串BuildDependentPropertyId(ModelMetadata元数据,ViewContext)
{
string depProp=viewContext.ViewData.TemplateInfo.GetFullHtmlFieldDid(this.DependentProperty);
//这将在开头追加当前字段的名称,因为TemplateInfo的上下文已将此字段名称追加到它。
var thisField=metadata.PropertyName+“\uux”;
if(depProp.StartsWith(此字段))
{
depProp=depProp.Substring(thisField.Length);
}
返回depProp;
}
}

有很多关于创建自定义验证属性的文章,但下面是一个示例,说明在您的案例中可能会出现的情况:

public class GreaterThanAttribute : ValidationAttribute
{
    public string PropertyNameToCompare { get; set; }

    public GreaterThanAttribute(string propertyNameToCompare)
    {
        PropertyNameToCompare = propertyNameToCompare;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var propertyToCompare = validationContext.ObjectType.GetProperty(PropertyNameToCompare);
        if (propertyToCompare == null)
        {
            return new ValidationResult(
                string.Format("Invalid property name '{0}'", PropertyNameToCompare));
        }
        var valueToCompare = propertyToCompare.GetValue(validationContext.ObjectInstance, null);

        bool valid;

        if (value is decimal && valueToCompare is decimal)
        {
            valid = ((decimal) value) > ((decimal) valueToCompare);
        }
        //TODO: Other types
        else
        {
            return new ValidationResult("Compared properties should be numeric and of the same type.");
        }

        if (valid)
        {
            return ValidationResult.Success;
        }

        return new ValidationResult(
            string.Format("{0} must be greater than {1}",
                validationContext.DisplayName, PropertyNameToCompare));
    }
}
我不太喜欢我开始检查房产类型的地方,但我不知道是否有可能让它变得更好


当然,您还需要实现
GreaterThanAttribute

您使用哪种验证?数据注释属性?哦,是的数据注释但是如果我想使用数据注释,结构会不同,对吗?结构关于什么?其用途与普通注释类似。您将放置[RequiredIf]属性。在我的示例中,您可以这样使用:[RequiredIf(“OnRequest”,true,ErrorMessageResourceName=“ValueRequired”,ErrorMessageResourceType=typeof(Resources.property))]
public class GreaterThanAttribute : ValidationAttribute
{
    public string PropertyNameToCompare { get; set; }

    public GreaterThanAttribute(string propertyNameToCompare)
    {
        PropertyNameToCompare = propertyNameToCompare;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var propertyToCompare = validationContext.ObjectType.GetProperty(PropertyNameToCompare);
        if (propertyToCompare == null)
        {
            return new ValidationResult(
                string.Format("Invalid property name '{0}'", PropertyNameToCompare));
        }
        var valueToCompare = propertyToCompare.GetValue(validationContext.ObjectInstance, null);

        bool valid;

        if (value is decimal && valueToCompare is decimal)
        {
            valid = ((decimal) value) > ((decimal) valueToCompare);
        }
        //TODO: Other types
        else
        {
            return new ValidationResult("Compared properties should be numeric and of the same type.");
        }

        if (valid)
        {
            return ValidationResult.Success;
        }

        return new ValidationResult(
            string.Format("{0} must be greater than {1}",
                validationContext.DisplayName, PropertyNameToCompare));
    }
}