選單
GSS 技術部落格
在這個園地裡我們將從技術、專案管理、客戶對談面和大家分享我們多年的經驗,希望大家不管是喜歡或是有意見,都可以回饋給我們,讓我們有機會和大家對話並一起成長!
若有任何問題請來信:gss_crm@gss.com.tw
3 分鐘閱讀時間 (634 個字)

Asp.Net MVC Model Validation:Custom Validation - 以 Required If 為例

Asp.Net MVC Model Validation:Custom Validation - 以 Required If 為例
在前篇「Asp.Net MVC Model Validation:Remote validation」的介紹之下,想必大家對於 .Net MVC 的 Model Validation 運作機制都有一定程度的了解,接下來將進一步介紹如何在 .Net MVC Model Validation 的運作機制加上自訂驗證規則(前、後端,使我們專案的表單驗證機制更加完善



自訂驗證規則的實作要素分為後端前端,以下將以 RequiredIf 的使用情境來說明:
後端
  • 自訂一個 Validation Attribute 類別(RequiredIfAttribute.cs),並:
    1. 繼承 ValidationAttribute 類別後覆寫 IsValid 方法來加入自訂驗證規則:後端 ModelState.IsValid 所觸發的驗證方法。
    2. 繼承 IClientValidatable 類別後實作 GetClientValidationRules 方法:當 .Net MVC framework 運作時,會透過此 interface 找到有實作的類別來取得 validation object,再透過 GetClientValidationRules 檢索及發送相關的 metadata 或 rules 至前端。(貼心小叮嚀:要提供前端驗證時,一定要實作此步驟)

[source language="csharp"]
public class RequiredIfAttribute : ValidationAttribute, IClientValidatable
{
private String PropertyName { get; set; }
private Object DesiredValue { get; set; }
private readonly RequiredAttribute _innerAttribute;

public RequiredIfAttribute(String propertyName, Object desiredvalue)
{
PropertyName = propertyName;
DesiredValue = desiredvalue;
_innerAttribute = new RequiredAttribute();
}

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var dependentValue = validationContext.ObjectInstance.GetType().GetProperty(PropertyName).GetValue(validationContext.ObjectInstance, null);
if (dependentValue != null && dependentValue.ToString() == DesiredValue.ToString() && !_innerAttribute.IsValid(value))
{
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName), new[] { validationContext.MemberName });
}
return ValidationResult.Success;
}

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule
{
ErrorMessage = string.Format("{0} 欄位是必要項。", metadata.GetDisplayName()),
ValidationType = "requiredif",
};
rule.ValidationParameters["dependentproperty"] = PropertyName;
rule.ValidationParameters["desiredvalue"] = DesiredValue is bool ? DesiredValue.ToString().ToLowerInvariant() : DesiredValue;
yield return rule;
}
}
[/source]

前端 
  • 建立一個 JS 檔案(jquery.requiredIfValidator.js),並:
    1. 透過 $.validator.unobtrusive.adapters.add 來定義自訂驗證規則的 Html 語法及額外(含參數)的設定程序。
    2. 透過 $.validator.addMethod 加入自訂驗證規則:為前端 $('form').valid() 所觸發的驗證方法。(貼心小叮嚀:如果僅需實作純前端驗證,實作此步驟即可完成)

[source language="js"]
// 將 Html 相關語法及參數的設定透過 unobtrusive adapters 新增進 jQuery validator
$.validator.unobtrusive.adapters.add('requiredif', ['dependentproperty', 'desiredvalue'], function (options) {
options.rules['requiredif'] = options.params;
options.messages['requiredif'] = options.message;
});

$(document).ready(function () {

// 註冊 jQuery validator 的 requiredif 自訂規則驗證方法
$.validator.addMethod('requiredif', function (value, element, parameters) {
var desiredvalue = parameters.desiredvalue;
desiredvalue = (desiredvalue == null ? '' : desiredvalue).toString();
var controlType = $("input[name$='" + parameters.dependentproperty + "']").attr("type");
var actualvalue = {}
if (controlType == "checkbox" || controlType == "radio") {
var control = $("input[name$='" + parameters.dependentproperty + "']:checked");
actualvalue = control.val();
} else {
actualvalue = $("#" + parameters.dependentproperty).val();
}
if ($.trim(desiredvalue).toLowerCase() === $.trim(actualvalue).toLocaleLowerCase()) {
var isValid = $.validator.methods.required.call(this, value, element, parameters);
return isValid;
}
return true;
});

});
[/source]

結果展示(DEMO)
將 Model 中需要驗證的 Property 掛上 DataAnnotation:RequiredIf 即完成設定與實作:








希望透過以上的介紹,
對大家往後實作 .Net MVC Model Validation 自訂驗證規則能有所幫助。
IBotDataStore.FlushAsync Exception: The data is ch...
RxJS observable V.S Mobx observable

相關文章

 

評論

尚無評論
已經注冊了? 這裡登入
Guest
2024/05/04, 週六

Captcha 圖像