RequiredAttribute z AllowEmptyString = true w ASP.NET MVC 3 unobtrusive validation
Jeśli mam [Required(AllowEmptyStrings = true)]
deklaracja w moim modelu widoku, Walidacja jest zawsze uruchamiana przy pustych wejściach. Znalazłem Artykuł który wyjaśnia dlaczego tak się dzieje. Czy wiesz, czy jest dostępna poprawka? Jeśli nie, to jak sobie z tym radzisz?
2 answers
Uwaga: zakładam, że masz AllowEmptyStrings = true, ponieważ używasz modelu widoku poza scenariuszem sieciowym; w przeciwnym razie nie wydaje się, aby wymagane atrybuty zezwalały na puste ciągi w scenariuszu sieciowym.
Istnieją trzy kroki, aby sobie z tym poradzić:
- Tworzenie niestandardowego adaptera atrybutów, który dodaje parametr walidacji
- zarejestruj swój adapter jako fabrykę adapterów
- Override jQuery Funkcja walidacji pozwalająca na puste ciągi znaków, gdy ten atrybut jest obecny
Krok 1: Niestandardowy adapter atrybutów
Zmodyfikowałem RequiredAttributeAdapter, aby dodać w tej logice:
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 };
}
}
}
Punkt 2. Zarejestruj to w swoim 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);
}
Punkt 3. Override the jQuery "required" validation function
Odbywa się to za pomocą jQuery.walidator.wywołanie addMethod (), dodając naszą niestandardową logikę, a następnie wywołanie oryginalnej funkcji - więcej o tym podejściu przeczytasz tutaj . Jeśli używasz tego w całej witrynie, być może w pliku skryptu, do którego odwołujesz się z _Layout.cshtml. Oto przykładowy blok skryptów, który możesz wrzucić na stronę w celu przetestowania:
<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>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-14 23:29:52
Zamiast dekorować wartość atrybutem "Required", używam poniższego. Uważam, że jest to najprostsze rozwiązanie tej kwestii.
[DisplayFormat (ConvertEmptyStringToNull=false)]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-09 07:02:42