Asp.Net MVC Validation - зависимые поля - PullRequest
7 голосов
/ 06 января 2010

В настоящее время я пытаюсь пройти проверку MVC и сталкиваюсь с некоторыми проблемами, когда поле требуется в зависимости от значения другого поля. Ниже приведен пример (который я еще не выяснил) - если PaymentMethod == "Check", то 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 для [Обязательный], а также расширил атрибут 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")]

Кто-нибудь имел опыт такого рода проверки? Будет ли лучше записать это в контроллер?

Спасибо за вашу помощь.

Ответы [ 4 ]

4 голосов
/ 18 февраля 2014

Просто используйте проверочную библиотеку Foolproof, которая доступна в Codeplex: https://foolproof.codeplex.com/

Поддерживаются следующие «обязательные» атрибуты / украшения проверки:

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

Начать легко:

  1. Скачать пакет можно по предоставленной ссылке
  2. Добавить ссылку на включенный DLL-файл
  3. Импорт включенных файлов JavaScript
  4. Убедитесь, что ваши представления ссылаются на включенные файлы JavaScript изнутри его HTML-кода для ненавязчивой проверки JavaScript и проверки jquery.
4 голосов
/ 14 августа 2013

Если вам нужна проверка на стороне клиента в дополнение к проверке модели на сервере, я думаю, что лучший способ - это настраиваемый атрибут проверки (как предложил Ярослав). Я включил здесь источник того, который я использую.

Пользовательский атрибут:

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; }
3 голосов
/ 06 января 2010

Я бы написал логику проверки в модели, а не в контроллере. Контроллер должен обрабатывать только взаимодействие между представлением и моделью. Поскольку эта модель требует проверки, я думаю, что она широко рассматривается как место для логики проверки.

Для проверки, которая зависит от значения другого свойства или поля, я (к сожалению) не вижу, как полностью избежать написания некоторого кода для этого в модели, такого как показано в книге Wrox ASP.NET MVC, sort как:

public bool IsValid
{
  get 
  {
    SetRuleViolations();
    return (RuleViolations.Count == 0); 
  }
}

public void SetRuleViolations()
{
  if (this.PaymentMethod == "Cheque" && String.IsNullOrEmpty(this.ChequeName))
  {
    RuleViolations.Add("Cheque name is required", "ChequeName");
  }
}

Было бы замечательно сделать всю декларативную проверку. Я уверен, что вы могли бы сделать RequiredDependentAttribute, но это бы обрабатывало только этот один тип логики. Еще более сложный материал потребует еще одного довольно специфического атрибута и т. Д., Который быстро сходит с ума.

2 голосов
/ 14 августа 2013

Ваша проблема может быть решена относительно просто с помощью атрибута условной проверки например

[RequiredIf("PaymentMethod == 'Cheque'")]
public string ChequeName { get; set; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...