RequiredAttribute с AllowEmptyString=true в ASP.NET MVC 3 ненавязчивая проверка
Если у меня есть [Required(AllowEmptyStrings = true)]
объявление в моей модели представления проверка всегда запускается на пустых входах. Я нашел статьи что объясняет, почему это происходит. Вы не знаете, есть ли исправление? Если нет, то как вы справляетесь с этим?
2 ответов
примечание: Я предполагаю, что у вас есть AllowEmptyStrings = true, потому что вы также используете свою модель представления вне веб-сценария; в противном случае не похоже, что есть смысл иметь обязательный атрибут, который позволяет пустые строки в веб-сценарии.
есть три шага, чтобы справиться с этим:
- создайте пользовательский адаптер атрибутов, который добавляет этот параметр проверки
- зарегистрируйте адаптер в качестве адаптера фабрика
- переопределите функцию проверки 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. Регистрировать это в глобальном.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.валидатор.вызов 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>
вместо того, чтобы украшать значение атрибутом "Required", я использую следующее. Я считаю, что это самое простое решение этой проблемы.
[DisplayFormat (ConvertEmptyStringToNull=false)]