Подтвердить что ты не робот

Группы проверки ASP.NET MVC?

У меня есть форма, в которой я хотел бы потребовать разные поля, в зависимости от того, какая кнопка отправки нажата. Пример: поле "А" требуется, если вы нажмете кнопку "Отправить" 1, но только поле "В" требуется, если вы нажмете кнопку "Отправить" 2. Если я все еще использую веб-формы, я бы назначил разные "группы проверки" каждой комбинации кнопок/валидатора. Есть ли способ сделать это в MVC, желательно с аннотациями данных на модели? Я бы предпочел реализовать проверку клиента и сервера с помощью одного решения, но я возьму то, что я могу получить...

Спасибо заранее!

4b9b3361

Ответ 1

Как насчет активированного атрибута проверки с проверкой проверки клиента (так что вы получаете как проверку клиента, так и сервер)? В приведенном ниже решении используется ненавязчивая проверка jQuery. Чтобы использовать это, вам нужно будет указать все свои собственные имена и передать имя атрибуту проверки. Кнопка также должна иметь какое-то значение, чтобы ее можно было отправить назад (так что код на стороне сервера может проверить ее, т.е. <input type="submit" name="myButton" value="1" />). Я не тестировал этот код, поэтому я не уверен, что он исчерпан. Возможно, вам понадобится сделать несколько модов:

Атрибут проверки для вашей модели:

public class RequiredIfButtonClickedAttribute : ValidationAttribute, IClientValidatable
{
    private RequiredAttribute _innerAttribute = new RequiredAttribute();
    public string ButtonName { get; set; }

    public RequiredIfButtonClickedAttribute(string buttonName)
    {
        ButtonName = buttonName;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if ((value == null && !string.IsNullOrEmpty(HttpContext.Current.Request.Form[ButtonName])))
        {
            if (!_innerAttribute.IsValid(value))
            {
                return new ValidationResult(this.ErrorMessage, new[] { validationContext.MemberName });
            }
        }

        return ValidationResult.Success;
    }

    #region IClientValidatable Members

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule() { ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()), ValidationType = "requiredifbuttonclicked" };
        rule.ValidationParameters.Add("buttonname", ButtonName);
        yield return rule;
    }

    #endregion
}

Клиент script:

/// <reference path="jquery-1.4.4-vsdoc.js" />
/// <reference path="jquery.validate.unobtrusive.js" />

// When a button is clicked remove the clicked button class from all buttons and add it to the on that was clicked
$(":submit").click(function () {
    $(":submit").removeClass('clickedButton');
    $(this).addClass('clickedButton');
});

$.validator.addMethod('requiredifbuttonclicked',
    function (value, element, parameters) {

        // if the condition is true, reuse the existing 
        // required field validator functionality
        if ($(".clickedButton").val("name") === parameters['buttonname'])
            return $.validator.methods.required.call(
              this, value, element, parameters);

        return true;
    }
);

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

И используйте его следующим образом:

[RequiredIfButtonClicked("myButtonName")]
public string Name { get; set; }

Ответ 2

Вы можете указать одно и то же имя для каждой кнопки отправки и другого значения. Затем у вас есть свойство в вашей модели просмотра, имеющее это имя типа string. Когда форма отправлена, ее значение будет соответствовать значению кнопки, на которую была нажата кнопка. Теперь вы можете создать собственный атрибут проверки подлинности, который будет использоваться для украшения вашей модели представления. В своей реализации IsValid вы получите экземпляр вашей модели представления и на основе значения специального свойства, которое вы будете выполнять валидации. Это уродливо, я знаю, но DataAnnotations действительно полезны для простых ситуаций проверки, но когда вы начинаете писать приложения реального мира, вы осознаете их ограничения.

Лично я использую FluentValidation.NET, и такой сценарий, как описанный здесь, довольно тривиально реализовать.