21

爲了創建一個自定義驗證屬性,我還在互聯網上跟蹤了一些文章和教程,這些屬性也支持客戶端驗證在asp.net mvc 4網站。這是我到現在爲止:自定義驗證屬性中的客戶端驗證 - asp.net mvc 4

RequiredIfAttribute.cs

[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] //Added 
public class RequiredIfAttribute : ValidationAttribute, IClientValidatable 
{ 
    private readonly string condition; 
    private string propertyName; //Added 

    public RequiredIfAttribute(string condition) 
    { 
     this.condition = condition; 
     this.propertyName = propertyName; //Added 
    } 

    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     PropertyInfo propertyInfo = validationContext.ObjectType.GetProperty(this.propertyName); //Added 
     Delegate conditionFunction = CreateExpression(validationContext.ObjectType, _condition); 
     bool conditionMet = (bool)conditionFunction.DynamicInvoke(validationContext.ObjectInstance); 

     if (conditionMet) 
     { 
      if (value == null) 
      { 
       return new ValidationResult(FormatErrorMessage(null)); 
      } 
     } 

     return ValidationResult.Success; 
    } 

    private Delegate CreateExpression(Type objectType, string expression) 
    { 
     LambdaExpression lambdaExpression = System.Linq.Dynamic.DynamicExpression.ParseLambda(objectType, typeof(bool), expression); //Added 
     Delegate function = lambdaExpression.Compile(); 
     return function; 
    } 

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
    { 
     var modelClientValidationRule = new ModelClientValidationRule 
     { 
      ValidationType = "requiredif", 
      ErrorMessage = ErrorMessage //Added 
     }; 

     modelClientValidationRule.ValidationParameters.Add("param", this.propertyName); //Added 
     return new List<ModelClientValidationRule> { modelClientValidationRule }; 
    } 
} 

然後我在一個類的屬性應用這個屬性這樣

[RequiredIf("InAppPurchase == true", "InAppPurchase", ErrorMessage = "Please enter an in app purchase promotional price")] //Added "InAppPurchase" 
public string InAppPurchasePromotionalPrice { get; set; } 

public bool InAppPurchase { get; set; } 

所以我想做的事當InAppPurchase字段爲真(表示在表單中檢查)時,顯示一條錯誤消息,表示InAppPurchasePromotionalPrice字段是必需的。以下是相關的代碼形式的觀點:

<div class="control-group"> 
       <label class="control-label" for="InAppPurchase">Does your app include In App Purchase?</label> 
       <div class="controls"> 
        @Html.CheckBoxFor(o => o.InAppPurchase) 
        @Html.LabelFor(o => o.InAppPurchase, "Yes") 
       </div> 
      </div> 
      <div class="control-group" id="InAppPurchasePromotionalPriceDiv" @(Model.InAppPurchase == true ? Html.Raw("style='display: block;'") : Html.Raw("style='display: none;'"))> 
       <label class="control-label" for="InAppPurchasePromotionalPrice">App Friday Promotional Price for In App Purchase: </label> 
       <div class="controls"> 
        @Html.TextBoxFor(o => o.InAppPurchasePromotionalPrice, new { title = "This should be at the lowest price tier of free or $.99, just for your App Friday date." }) 
        <span class="help-inline"> 
         @Html.ValidationMessageFor(o => o.InAppPurchasePromotionalPrice) 
        </span> 
       </div> 
      </div> 

此代碼的工作完美,但是當我提交表單是爲了顯示該消息所請求的服務器上的完整的文章。所以我創建JavaScript代碼來實現客戶端驗證:

requiredif.js

(function ($) { 
    $.validator.addMethod('requiredif', function (value, element, params) { 
     /*var inAppPurchase = $('#InAppPurchase').is(':checked'); 

     if (inAppPurchase) { 
      return true; 
     } 

     return false;*/ 

     var isChecked = $(param).is(':checked'); 

     if (isChecked) { 
      return false; 
     } 

     return true; 
    }, ''); 

    $.validator.unobtrusive.adapters.add('requiredif', ['param'], function (options) { 
     options.rules["requiredif"] = '#' + options.params.param; 
     options.messages['requiredif'] = options.message; 
    }); 
})(jQuery); 

這是MSDN和教程所提出的方法我已經找到

當然,我也插形式所需的腳本:

  1. jquery.unobtrusive-ajax.min.js
  2. 個jquery.validate.min.js
  3. jquery.validate.unobtrusive.min.js
  4. requiredif.js

但...客戶端驗證仍然無法正常工作。所以你能幫我找到我缺少的東西嗎?提前致謝。

回答

28

看看這個:http://thewayofcode.wordpress.com/tag/custom-unobtrusive-validation/

使用本教程中我沒有問題,運行我的自定義驗證代碼。我可以在代碼中發現的唯一區別就是您創建$.validator.unobtrusive.adapters.add函數的方式。參數有點不同,但是,問題可能只是您沒有定義適配器的rule部分。

嘗試使用這樣的事情:

$.validator.unobtrusive.adapters.add("requiredif", ["requiredif"], function (options) { 
    options.rules["requiredif"] = "#" + options.params.requiredif; 
    options.messages["requiredif"] = options.message; 
}); 

或本

$.validator.unobtrusive.adapters.add("requiredif", function (options) { 
    options.rules["requiredif"] = "#" + options.element.name.replace('.', '_'); // mvc html helpers 
    options.messages["requiredif"] = options.message; 
}); 

關於rule(從鏈接所):

jQuery的規則陣列此HTML元素。預計適配器 將項目添加到此規則數組,以便爲​​其要附加的特定jQuery Validate 驗證程序。該名稱是jQuery的名稱 驗證規則,該值是jQuery的參數值 驗證規則。

+1

謝謝你的回答。我將你的問題標記爲答案,因爲這篇文章和你的代碼幫助我理解了規則數組的使用並找到了解決方案。我編輯了我的問題,現在完成了我的項目。謝謝 –

0

值得一提的是,[RequiredIf]屬性需要添加到視圖模型中的第二個窗體域,以便客戶端驗證工作。