2015-02-23 122 views
0

我有以下POCO:如何验证客户端验证中的双变量规则?

public class CabinetItem 
{ 
    [Required] 
    [Display(...)] 
    public double Width { get; set; } 

    public double MinWidth { get; } 
} 

我试图搞清楚的是我如何验证WidthMinWidth较大时MinWidth可能是什么吗?最小宽度是一个依赖于橱柜项目的约束。注意:我还遗漏了一个MaxWidth来简化这个问题。

+0

看看我的答案,它包括unobtrusivevalidation – sabotero 2015-02-23 17:09:36

回答

0

您可以创建一个CustomValidationAttribute

以此为考试PLE:

public class GreaterThanAttribute : ValidationAttribute, IClientValidatable 
    { 
     private readonly string _testedPropertyName; 
     private readonly bool _allowEqualValues; 
     private readonly string _testedPropertyDisplayName; 

     public override string FormatErrorMessage(string displayName) 
     { 
      return string.Format(ErrorMessages.GreaterThan_Message, displayName, _testedPropertyDisplayName); 
     } 

     public GreaterThanAttribute(string testedPropertyName, Type resourceType, string testedPropertyDisplayNameKey, bool allowEqualValues = false) 
     { 
      _testedPropertyName = testedPropertyName; 
      _allowEqualValues = allowEqualValues; 
      var rm = new ResourceManager(resourceType); 
      _testedPropertyDisplayName = rm.GetString(testedPropertyDisplayNameKey);    
     } 

     protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
     { 
      var propertyTestedInfo = validationContext.ObjectType.GetProperty(_testedPropertyName); 

      if (propertyTestedInfo == null) 
      { 
       return new ValidationResult(string.Format("unknown property {0}", _testedPropertyName)); 
      } 

      var propertyTestedValue = propertyTestedInfo.GetValue(validationContext.ObjectInstance, null); 

      if (value == null || !(value is Decimal)) 
      { 
       return ValidationResult.Success; 
      } 

      if (propertyTestedValue == null || !(propertyTestedValue is Decimal)) 
      { 
       return ValidationResult.Success; 
      } 

      // Compare values 
      if ((Decimal)value >= (Decimal)propertyTestedValue) 
      { 
       if (_allowEqualValues && value == propertyTestedValue) 
       { 
        return ValidationResult.Success; 
       } 
       else if ((Decimal)value > (Decimal)propertyTestedValue) 
       { 
        return ValidationResult.Success; 
       } 
      } 

      return new ValidationResult(FormatErrorMessage(validationContext.DisplayName)); 
     } 

     public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
     { 
      var rule = new ModelClientValidationRule 
      { 
       ErrorMessage = FormatErrorMessage(metadata.DisplayName), 
       ValidationType = "greaterthan" 
      }; 
      rule.ValidationParameters["propertytested"] = _testedPropertyName; 
      rule.ValidationParameters["allowequalvalues"] = _allowEqualValues; 
      yield return rule; 
     } 
    } 

您可以使用它像这样:

public Decimal MyProperty1 { get; set; } 

[GreaterThanAttribute("MyProperty1", typeof(Strings), "Error_String")] 
public Decimal MyProperty2 { get; set; } 

[GreaterThanAttribute("MyProperty2", typeof(Strings), "Error_String")] 
public Decimal MyProperty3 { get; set; } 

,以及在客户端,您可以添加此客户端验证:

jQuery.validator.unobtrusive.adapters.add('greaterthan', ['propertytested', 'allowequalvalues'], function (options) { 
      options.params["allowequalvalues"] = options.params["allowequalvalues"] === "True" || 
               options.params["allowequalvalues"] === "true" || 
               options.params["allowequalvalues"] === true ? true : false; 

      options.rules['greaterthan'] = options.params; 
      options.messages['greaterthan'] = options.message; 
     }); 
jQuery.validator.addMethod("greaterthan", function (value, element, params) {   
      var properyTestedvalue= $('input[name="' + params.propertytested + '"]').val(); 
      if (!value || !properyTestedvalue) return true; 
      return (params.allowequalvalues) ? parseFloat(properyTestedvalue) <= parseFloat(value) : parseFloat(properyTestedvalue) < parseFloat(value); 
     }, ''); 
+0

这可能会奏效。但是我没有直接向客户发送最大宽度。我是一个隐藏的价值。 – Jordan 2015-02-23 18:28:11

+0

以及'$('input [name =''+ params.propertytested +'“'')')即使是隐藏字段 – sabotero 2015-02-23 21:26:14

+0

,您也必须使用@ Html.HiddenFor(m => m.MinWith)'渲染隐藏的字段 – sabotero 2015-02-23 21:30:56

1

选项1:

foolproof NuGet包可能是你的情况是非常有用的。

安装foolproof NuGet包,并使用其额外的有用的属性如下所示:

public class CabinetItem 
{ 
    [Required] 
    [Display(...)] 
    [GreaterThan("MinWidth")] 
    public double Width { get; set; } 

    public double MinWidth { get; } 
} 

还有一些其他的功能,以及:

  • [是]
  • [EqualTo]
  • [NotEqualTo]
  • [GreaterThan]
  • [每种不超过]
  • [GreaterThanOrEqualTo]
  • [LessThanOrEqualTo]

资源:Is there a way through data annotations to verify that one date property is greater than or equal to another date property?

+0

您链接到的自定义验证属性仅适用于Silverlight。我相信MVC的模拟将是ValidationAttribute。如果情况并非如此,请纠正我。 – Jordan 2015-02-23 16:54:21

+0

我已经看到这个,但是这不需要回发到服务器来验证?这是幕后的不显眼的验证吗? – Jordan 2015-02-23 16:54:51

+0

是的,你是正确的第一个我会删除它,但第二个不显眼的ajax可以是任何获取/发布方法。请看看http://www.asp.net/mvc/overview/older-versions/creating-a-mvc-3-application-with-razor-and-unobtrusive-javascript – Tushar 2015-02-23 16:59:33