У меня есть следующий класс, используемый для пользовательской проверки:

[AttributeUsage(AttributeTargets.Property, AllowMultiple=false, Inherited=true)]
public sealed class RequiredIfAnyTrueAttribute : ValidationAttribute, IClientValidatable
{
    private const string DefaultErrorMessage = "{0} is required";

    public List<string> OtherProperties { get; private set; }

    public RequiredIfAnyTrueAttribute(string otherProperties)
        : base(DefaultErrorMessage)
    {
        if (string.IsNullOrEmpty(otherProperties))
            throw new ArgumentNullException("otherProperty");

        OtherProperties = new List<string>(otherProperties.Split(new char[] { '|', ',' }));
    }

    public override string FormatErrorMessage(string name)
    {
        return string.Format(ErrorMessageString, name);
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (value == null)
        {
            foreach (string s in OtherProperties)
            {
                var otherProperty = validationContext.ObjectType.GetProperty(s);
                var otherPropertyValue = otherProperty.GetValue(validationContext.ObjectInstance, null);

                if (otherPropertyValue.Equals(true))
                    return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
            }
        }

        return ValidationResult.Success;
    }

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

        clientValidationRule.ValidationParameters.Add("otherproperties", string.Join("|",OtherProperties));

        return new[] { clientValidationRule };
    }
}

Моя модель просмотра:

public class SampleViewModel
{
    public bool PropABC { get; set; }
    public bool PropXYZ { get; set; }

    [RequiredIfAnyTrue("PropABC|PropXYZ")]
    public int? TestField { get; set; }
}

Когда отображается мое строго типизированное представление, все работает нормально. Если выбрано PropABC или PropXYZ, мне необходимо ввести значение для TestField. Возможна проверка как на стороне клиента, так и на стороне сервера.

Однако с учетом следующей последовательности событий:

  1. проверить PropABC
  2. представить форму
  3. на стороне клиента запускается проверка для TestField требуется
  4. снимите флажок с PropABC
  5. проверка клиента не запускается повторно, и сообщение проверки остается до отправки формы

Чтобы решить # 5, я обычно прикрепляю события щелчка к флажкам через jquery onready, чтобы повторно выполнить проверку.

Есть ли предпочтительный / рекомендуемый способ принудительной проверки на стороне клиента вручную с учетом MVC3 + ненавязчивый + jquery?

0
Shawn 25 Авг 2011 в 22:29

3 ответа

Лучший ответ

Шон, привязанность к событиям - лучший способ получить подтверждение для повторения.

Я бы предложил создать класс под названием «проверка» (или что-то в этом роде), добавить его к каждому элементу для проверки, а затем использовать jQuery для присоединения к событиям щелчка и размытия (и, возможно, к событию изменения) каждого элемента с помощью этот класс и проверьте элемент следующим образом:

$("form").validate().element(this);
1
counsellorben 28 Авг 2011 в 13:57

Вам нужно написать свои собственные атрибуты? В противном случае, я думаю, вы сможете избежать «изобретать колесо».

FoolProof отлично работает. вы получаете его как пакет NuGet.

NuGet: install-package foolproof

Он включает в себя множество отличных атрибутов для различных комбинаций требуемых на лету полей и тому подобного.

1
Doug Chamberlain 25 Авг 2011 в 18:45

FoolProof все еще находится в стадии бета-тестирования и не работает с вложенной моделью просмотра, а также с массивами.

0
Eric Gontier 6 Ноя 2013 в 13:45