Asp.net

Asp.Net MVC 驗證 - 依賴欄位

  • December 9, 2015

我目前正在嘗試通過 MVC 驗證工作,並且遇到了一些問題,即根據另一個欄位的值需要一個欄位。下面是一個範例(我還沒有弄清楚) - 如果 PaymentMethod == “Cheque”,則應該需要 ChequeName,否則可以通過。

[Required(ErrorMessage = "Payment Method must be selected")]
public override string PaymentMethod
{ get; set; }

[Required(ErrorMessage = "ChequeName is required")]
public override string ChequeName
{ get; set; }

我正在使用 System.ComponentModel.DataAnnotations

$$ Required $$,並且還擴展了 ValidationAttribute 以嘗試使其正常工作,但我無法通過變數進行驗證(下面的擴展)

public class JEPaymentDetailRequired : ValidationAttribute 
{
   public string PaymentSelected { get; set; }
   public string PaymentType { get; set; }

   public override bool IsValid(object value)
   {
       if (PaymentSelected != PaymentType)
           return true;
       var stringDetail = (string) value;
       if (stringDetail.Length == 0)
           return false;
       return true;
   }
}

執行:

[JEPaymentDetailRequired(PaymentSelected = PaymentMethod, PaymentType = "Cheque", ErrorMessage = "Cheque name must be completed when payment type of cheque")]

有沒有人有過這種驗證的經驗?將它寫入控制器會更好嗎?

謝謝你的幫助。

如果除了伺服器上的模型驗證之外還需要客戶端驗證,我認為最好的方法是自定義驗證屬性(如 Jaroslaw 建議的那樣)。我在這裡包括我使用的來源。

自定義屬性:

public class RequiredIfAttribute : DependentPropertyAttribute
{
   private readonly RequiredAttribute innerAttribute = new RequiredAttribute();

   public object TargetValue { get; set; }


   public RequiredIfAttribute(string dependentProperty, object targetValue) : base(dependentProperty)
   {
       TargetValue = targetValue;
   }


   protected override ValidationResult IsValid(object value, ValidationContext validationContext)
   {
       // get a reference to the property this validation depends upon
       var containerType = validationContext.ObjectInstance.GetType();
       var field = containerType.GetProperty(DependentProperty);

       if (field != null)
       {
           // get the value of the dependent property
           var dependentvalue = field.GetValue(validationContext.ObjectInstance, null);

           // compare the value against the target value
           if ((dependentvalue == null && TargetValue == null) ||
               (dependentvalue != null && dependentvalue.Equals(TargetValue)))
           {
               // match => means we should try validating this field
               if (!innerAttribute.IsValid(value))
                   // validation failed - return an error
                   return new ValidationResult(ErrorMessage, new[] { validationContext.MemberName });
           }
       }

       return ValidationResult.Success;
   }

   public override IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
   {
       var rule = new ModelClientValidationRule
                      {
                          ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
                          ValidationType = "requiredif"
                      };

       var depProp = BuildDependentPropertyId(DependentProperty, metadata, context as ViewContext);

       // find the value on the control we depend on;
       // if it's a bool, format it javascript style 
       // (the default is True or False!)
       var targetValue = (TargetValue ?? "").ToString();
       if (TargetValue != null)
           if (TargetValue is bool)
               targetValue = targetValue.ToLower();

       rule.ValidationParameters.Add("dependentproperty", depProp);
       rule.ValidationParameters.Add("targetvalue", targetValue);

       yield return rule;
   }
}

Jquery 驗證擴展:

$.validator.unobtrusive.adapters.add('requiredif', ['dependentproperty', 'targetvalue'], function (options) {
   options.rules['requiredif'] = {
       dependentproperty: options.params['dependentproperty'],
       targetvalue: options.params['targetvalue']
   };
   options.messages['requiredif'] = options.message;
});

$.validator.addMethod('requiredif',
   function (value, element, parameters) {
       var id = '#' + parameters['dependentproperty'];

       // get the target value (as a string, 
       // as that's what actual value will be)
       var targetvalue = parameters['targetvalue'];
       targetvalue = (targetvalue == null ? '' : targetvalue).toString();

       // get the actual value of the target control
       var actualvalue = getControlValue(id);

       // if the condition is true, reuse the existing 
       // required field validator functionality
       if (targetvalue === actualvalue) {
           return $.validator.methods.required.call(this, value, element, parameters);
       }

       return true;
   }
);

使用屬性裝飾屬性:

[Required]
public bool IsEmailGiftCertificate { get; set; }

[RequiredIf("IsEmailGiftCertificate", true, ErrorMessage = "Please provide Your Email.")]
public string YourEmail { get; set; }

只需使用 Codeplex 上提供的 Foolproof 驗證庫: https ://foolproof.codeplex.com/

它支持以下“requiredif”驗證屬性/裝飾:

[RequiredIf]
[RequiredIfNot]
[RequiredIfTrue]
[RequiredIfFalse]
[RequiredIfEmpty]
[RequiredIfNotEmpty]
[RequiredIfRegExMatch]
[RequiredIfNotRegExMatch]

開始很容易:

  1. 從提供的連結下載包
  2. 添加對包含的 .dll 文件的引用
  3. 導入包含的 javascript 文件
  4. 確保您的視圖從其 HTML 中引用包含的 javascript 文件,以進行不顯眼的 javascript 和 jquery 驗證。

引用自:https://stackoverflow.com/questions/2009776