2013-04-16 35 views
1

我目前正在建設它通過數據註釋使用不引人注目的驗證一個MVC4項目。MVC禁用不引人注目的驗證具體的驗證

我有一個特定字段中,「POSTALCODE」,這既是[必需的]和具有附着到其上的[正則表達式]驗證器。 事情是,這個正則表達式只應該被選中,如果一個特定的國家被選中。 (這個國家將是默認值,我們可以假設在幾乎所有情況下這將被使用)

現在我需要某種方式來禁用此正則表達式驗證時,選擇不同的國家,同時保持所需的驗證程序處於活動狀態。

幾乎所有sollutions我發現使用的是jQuery.validator.defaults.ignore過濾器,但是這將在該項目上禁用這兩個驗證。

有關如何最好地解決此問題的任何想法?

編輯:小的代碼片段,顯示這是如何工作的。

[Required] 
[RegularExpression("^[1-9]\\d{3} ?[a-zA-Z]{2}$"] //Should only be verified if Country == "The Netherlands" 
string PostalCode{get;set;} 

[Required] 
string Country {get;set;} 

回答

1

在我做了我自己的ValidationAttribute基於此博客文章的結尾:http://thewayofcode.wordpress.com/2012/01/18/custom-unobtrusive-jquery-validation-with-data-annotations-in-mvc-3/ 這是一個優雅的sollution和需要的方式少於我預期的工作。

編輯:根據要求,我公司提供由自己創造的sollution:

// DependentRegularExpressionAttribute.cs 
    /// <summary> 
/// Only performs a regular expression validation if a specified other property meets a validation requirement 
/// </summary> 
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] 
public class DependentRegularExpressionAttribute : ValidationAttribute, IClientValidatable 
{ 
    private readonly Regex _regex; 
    private readonly string _otherPropertyName; 
    private readonly Regex _otherPropertyRegex; 

    public DependentRegularExpressionAttribute(string regex, string otherPropertyName, string otherPropertyRegex) 
    { 
     _regex = new Regex(regex); 
     _otherPropertyName = otherPropertyName; 
     _otherPropertyRegex = new Regex(otherPropertyRegex); 
    } 

    /// <summary> 
    /// Format the error message filling in the name of the property to validate and the reference one. 
    /// </summary> 
    /// <param name="name">The name of the property to validate</param> 
    /// <returns>The formatted error message</returns> 
    public override string FormatErrorMessage(string name) 
    { 
     return string.Format(ErrorMessageString, name, _regex, _otherPropertyName, _otherPropertyRegex); 
    } 

    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     var validationResult = ValidationResult.Success; 

     if (value == null || String.IsNullOrEmpty(value as string)) 
      return validationResult; 

     // Using reflection we can get a reference to the other property 
     var otherPropertyInfo = validationContext.ObjectType.GetProperty(_otherPropertyName); 
     var otherPropertyValue = otherPropertyInfo.GetValue(validationContext.ObjectInstance, null); 
     if (otherPropertyValue == null || String.IsNullOrEmpty(otherPropertyValue as string)) 
      return validationResult; 
     if (_otherPropertyRegex.IsMatch(otherPropertyValue.ToString())) 
     { 
      if (!_regex.IsMatch(value.ToString())) 
       validationResult = new ValidationResult(ErrorMessage); 
     } 


     return validationResult; 
    } 


    #region IClientValidatable Members 

    /// <summary> 
    /// 
    /// </summary> 
    /// <param name="metadata"></param> 
    /// <param name="context"></param> 
    /// <returns></returns> 
    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) 
    { 
     string errorMessage = FormatErrorMessage(metadata.DisplayName ?? metadata.PropertyName); 

     // The value we set here are needed by the jQuery adapter 
     var dependentRegexRule = new ModelClientValidationRule 
     { 
      ErrorMessage = errorMessage, 
      ValidationType = "dependentregex" 
     }; 
     //"otherpropertyname" is the name of the jQuery parameter for the adapter, must be LOWERCASE! 
     dependentRegexRule.ValidationParameters.Add("otherpropertyname", _otherPropertyName); 
     dependentRegexRule.ValidationParameters.Add("regex", _regex); 
     dependentRegexRule.ValidationParameters.Add("otherpropertyregex", _otherPropertyRegex); 

     yield return dependentRegexRule; 
    } 

    #endregion 

} 


    // customvalidation.js 
    $.validator.addMethod("dependentregex", function (value, element, params) { 
    var regex = new RegExp(params[0]); 
    var otherElement = document.getElementById(params[1]); 
    var otherElementRegex = new RegExp(params[2]); 

    if (!value || !otherElement.value) 
     return true; 

    if (otherElementRegex.test(otherElement.value)) { 
     if (!regex.test(element.value)) 
      return false; 
    } 
    return true; 
}); 

$.validator.unobtrusive.adapters.add("dependentregex", ["regex", "otherpropertyname", "otherpropertyregex"], function(options) { 
    options.rules["dependentregex"] = [options.params.regex, 
     options.params.otherpropertyname, 
     options.params.otherpropertyregex]; 
    options.messages["dependentregex"] = options.message; 
}); 

在我的視圖模型我做了以下內容:

 [Display(Name = "Customer_PostalCode", ResourceType = typeof(Resources.DisplayNames))] 
    [DependentRegularExpression("^[1-9]\\d{3} ?[a-zA-Z]{2}$", "CorrespondenceCountry", "Nederland", ErrorMessageResourceType = typeof(Resources.Validation), ErrorMessageResourceName = "Customer_PostalCode")] //"Nederland" is a regular expression in this case 
    [Required(ErrorMessageResourceType = typeof(Resources.Validation), ErrorMessageResourceName = "Shared_RequiredField")] 
    public string CorrespondenceZipCode { get; set; } 

在年底,customvalidation.js基本方法與C#代碼完全相同。什麼都沒有可以在博文中找到詳細的解釋,我引用

+0

您的解決方案可能會對其他人有用;你介意在你的回答中發佈一個簡單的例子嗎? –

+0

@TiesonT。好點子。用一段代碼編輯我的文章。 – Kippie

+0

你也可以接受你自己的答案。感謝您提供您的實施。 –

0

看起來好像你想要一個「required if」驗證屬性。我想看看http://foolproof.codeplex.com/ - 它,您可以使用像這樣(直接從該項目的網站解禁)的實現:

private class Person 
{ 
    [Required] 
    public string FirstName { get; set; } 

    [Required] 
    public string LastName { get; set; } 

    public bool Married { get; set; } 

    [RequiredIfTrue("Married")] 
    public string MaidenName { get; set; } 
} 
+0

不完全是,我會需要的是一個「正則表達式,如果」屬性。 請參閱我的編輯,瞭解我想要的更清晰的示例。 – Kippie

0

看看這個,我沒有用它自己,但它似乎滿足您的需求http://foolproof.codeplex.com/workitem/18974

他們有看起來像這樣的例子:

[RequiredIf("Country", Operator.RegExMatch, "(1033|4105)", ErrorMessage = "{0} is required")] 
public string State { get; set; } 

[Required(ErrorMessage = "{0} is required")] 
public int Country { get; set; } 
+0

正如上面的答案所示,所需的屬性不是有條件的屬性。我需要我的正則表達式被國家的價值切換。萬無一失似乎並不支持這一點。 (至少,我認爲是這樣,因爲他們沒有真正的文檔可用) – Kippie

+0

你能實現遠程驗證嗎?並通過選定的國家,檢查其荷蘭,並驗證或返回真正的荷蘭? http://stackoverflow.com/questions/4752877/remote-validation-in-as-net-mvc-3-how-to-use-additionalfields-in-action-method – christiandev

相關問題