2013-08-22 51 views
3

我有下一個(簡化的)視圖模型:ASP MVC複雜屬性的unobrusive驗證

public class RegisterModel 
{ 
    public string UserName { get; set; } 

    [MustExistIf("SomeProperty", "some value", "SomeOtherProperty", ErrorMessage = "You have to select something")] 
    public string LastName { get; set; } 

    public AddressModel Address { get; set; } 

} 

    public class AddressModel 
{ 
    public string Street { get; set; } 

    public string House { get; set; } 
} 

和我有自定義驗證

public class MustExistIfAttribute : ValidationAttribute, IClientValidatable 
{ 
    private string _masterName { get; set; } 

    private object _masterValue { get; set; } 

    private string _dependantName { get; set; } 

    public MustExistIfAttribute(string masterName, object masterValue, string dependantName) 
    { 
     this._masterName = masterName; 
     this._masterValue = masterValue; 
     this._dependantName = dependantName; 
    } 

    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     // get value of master property 
     var masValue = _getValue(validationContext.ObjectInstance, _masterName); 

     // get value of property whch depends on master property 
     var depValue = _getValue(validationContext.ObjectInstance, _dependantName); 

     if (masValue.Equals(_masterValue)) // if value in request is equal to value in specified in data annotation 
     { 
      if (depValue == null) // if dependant value does not exist 
      { 
       return new ValidationResult(FormatErrorMessage(validationContext.DisplayName)); 
      } 
     } 

     return ValidationResult.Success; 
    } 

    public override bool IsValid(object value) 
    { 
     return base.IsValid(value); 
    } 

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
    { 
     var modelClientValidationRule = new ModelClientValidationRule 
     { 
      ValidationType = "mustexistif", 
      ErrorMessage = FormatErrorMessage(metadata.DisplayName) 
     }; 
     modelClientValidationRule.ValidationParameters.Add("mastername", this._masterName); 
     modelClientValidationRule.ValidationParameters.Add("mastervalue", this._masterValue); 
     modelClientValidationRule.ValidationParameters.Add("dependantname", this._dependantName); 
     yield return modelClientValidationRule; 
    } 

    private static object _getValue(object objectInstance, string propertyName) 
    { 
... 
    } 
} 

我有下一個的JavaScript(請忽略返回在mustexitif方法假 - 它只是爲了測試目的)

(function() { 

    jQuery.validator.addMethod('mustexistif', function (value, element, params) { 
     var masterName = params['mastername']; 
     var masterValue = params['mastervalue']; 
     var dependantName = params['dependantname']; 
     return false; 
    }); 


    var setValidationValues = function (options, ruleName, value) { 
     options.rules[ruleName] = value; 
     if (options.message) { 
      options.messages[ruleName] = options.message; 
     } 
    }; 
    var $Unob = $.validator.unobtrusive; 

    $Unob.adapters.add("mustexistif", ["mastername", "mastervalue", "dependantname"], function (options) { 
     var value = { 
      mastername: options.params.mastername, 
      mastervalue: options.params.mastervalue, 
      dependantname: options.params.dependantname 
     }; 
     setValidationValues(options, "mustexistif", value); 
    }); 
})(); 

它的工作原理當我裝飾LastName屬性具有MustExistIf注​​解的RegisterModel類(如在提供的代碼中)。 但我真正想要的是使用MustExistIf注​​釋來修飾RegisterModel的複雜Address屬性。問題是,當我這樣做,沒有unobrusive適配器被註冊(JavaScript做這不是觸發)。因此,當我對簡單和複雜的屬性進行處理時,會有所不同。我的解決方案不允許我裝飾Address類的屬性(僅供參考,我試過了,然後驗證工作正常)。有沒有辦法完成我的目標?我錯過了什麼嗎? Woud解決方案是在模型層面進行驗證的?但是,是否有可能做客戶端驗證?

回答