2

現在、データ注釈による目立たない検証を使用する MVC4 プロジェクトを構築しています。

[必須]であり、[RegularExpression]バリデータが添付されている特定のフィールド「PostalCode」があります。問題は、この正規表現は、特定の国が選択されている場合にのみ検証する必要があるということです。(この国がデフォルト値となり、ほぼすべてのケースでこれが使用されると想定できます)

必要なバリデーターをアクティブに保ちながら、別の国が選択されたときにこの正規表現検証を無効にする方法が必要です。

私が見つけたほぼすべての解決策は 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;}
4

3 に答える 3

2

最後に、このブログ投稿に基づいて独自の ValidationAttribute を作成しました。 / 洗練されたソリューションであり、予想よりもはるかに少ない作業で済みます。

編集:リクエストに応じて、自分で作成したソリューションを提供します:

// 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# コードとまったく同じことを行います。すべてが何をするかの詳細な説明は、私が参照したブログ投稿にあります

于 2013-04-16T11:17:46.147 に答える
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; }
于 2013-04-16T09:13:28.237 に答える
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; }
}
于 2013-04-16T08:30:19.520 に答える