RequiredAttribute с AllowEmptyString = true в ненавязчивой проверке ASP.NET MVC 3 - PullRequest
21 голосов
/ 22 июня 2011

Если у меня есть объявление [Required(AllowEmptyStrings = true)] в моей модели представления, проверка всегда запускается на пустых входах. Я нашел статью , которая объясняет, почему это происходит. Вы знаете, есть ли исправление? Если нет, как вы справляетесь с этим?

Ответы [ 2 ]

22 голосов
/ 28 июня 2011

Примечание: я предполагаю, что у вас AllowEmptyStrings = true, потому что вы также используете свою модель представления вне веб-сценария; в противном случае, кажется, что нет особого смысла иметь атрибут Required, который допускает пустые строки в веб-сценарии.

Для этого есть три шага:

  1. Создание настраиваемого адаптера атрибута, который добавляет этот параметр проверки
  2. Зарегистрируйте свой адаптер как фабрику адаптеров
  3. Переопределить функцию проверки jQuery, чтобы разрешить пустые строки при наличии этого атрибута

Шаг 1: Адаптер пользовательских атрибутов

Я изменил RequiredAttributeAdapter для добавления в эту логику:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;

namespace CustomAttributes
{
    /// <summary>Provides an adapter for the <see cref="T:System.Runtime.CompilerServices.RequiredAttributeAttribute" /> attribute.</summary>
    public class RequiredAttributeAdapter : DataAnnotationsModelValidator<RequiredAttribute>
    {
        /// <summary>Initializes a new instance of the <see cref="T:System.Runtime.CompilerServices.RequiredAttributeAttribute" /> class.</summary>
        /// <param name="metadata">The model metadata.</param>
        /// <param name="context">The controller context.</param>
        /// <param name="attribute">The required attribute.</param>
        public RequiredAttributeAdapter(ModelMetadata metadata, ControllerContext context, RequiredAttribute attribute)
            : base(metadata, context, attribute)
        {
        }
        /// <summary>Gets a list of required-value client validation rules.</summary>
        /// <returns>A list of required-value client validation rules.</returns>
        public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
        {
            var rule = new ModelClientValidationRequiredRule(base.ErrorMessage);
            if (base.Attribute.AllowEmptyStrings)
            {
                //setting "true" rather than bool true which is serialized as "True"
                rule.ValidationParameters["allowempty"] = "true";
            }

            return new ModelClientValidationRequiredRule[] { rule };
        }
    }
}

Шаг 2. Зарегистрируйте это в вашем global.asax / Application_Start ()

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        DataAnnotationsModelValidatorProvider.RegisterAdapterFactory(typeof(RequiredAttribute),
          (metadata, controllerContext, attribute) => new CustomAttributes.RequiredAttributeAdapter(metadata,
            controllerContext, (RequiredAttribute)attribute)); 

        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);
    }

Шаг 3. Переопределить «обязательную» функцию проверки jQuery

Это делается с помощью вызова jQuery.validator.addMethod (), добавления нашей пользовательской логики и последующего вызова исходной функции - вы можете узнать больше об этом подходе здесь . Если вы используете это на своем сайте, возможно, в файле сценария, указанном в вашем _Layout.cshtml. Вот пример блока скрипта, который вы можете поместить на страницу для тестирования:

<script>
jQuery.validator.methods.oldRequired = jQuery.validator.methods.required;

jQuery.validator.addMethod("required", function (value, element, param) {
    if ($(element).attr('data-val-required-allowempty') == 'true') {
        return true;
    }
    return jQuery.validator.methods.oldRequired.call(this, value, element, param);
},
jQuery.validator.messages.required // use default message
);
</script>
15 голосов
/ 09 сентября 2013

Вместо того, чтобы украшать значение атрибутом 'Required', я использую следующее. Я считаю, что это самое простое решение этой проблемы.

[DisplayFormat (ConvertEmptyStringToNull = ложь)]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...