Вы используете DataAnnotations для проверки. Насколько я понимаю, вы ищете способ применить проверку DataAnnotation к каждому элементу списка.
Всякий раз, когда вызывается Html.EditorFor, он извлекает ModelMetadata модели, которая была передана ему, а затем извлекает все ModelValidators, связанные с этой моделью. Именно наличие этих ModelValidators приводит к атрибутам data-val-* в HTML.
Когда Html.EditorFor передается в виде списка в качестве модели (или любого перечисляемого, если на то пошло), он сначала извлекает ModelMetadata и связанные валидаторы для свойства — в вашем случае он извлекает ModelMetadata, связанный со свойством «MyField», за которым следует валидаторы — в данном случае «RegularExpression». Затем он перебирает список строк и получает ModelMetadata и Validators для каждой строки. Хотя ModelMetadata создается для каждой строки, для этих строк не указаны средства проверки. По этой причине строка отображается, но атрибуты проверки не добавляются в элемент HTML.
На мой взгляд, то, что вы ищете, может быть достигнуто путем добавления валидатора, указанного в свойстве MyField, ко всем элементам списка во время выполнения.
Это можно сделать с помощью
- Написание общего шаблона редактора для всех коллекций
- Установка текущего ModelMetadataProvider в DataAnnotationsModelMetadataProvider
- Переопределение метода GetValidators для DataAnnotationsModelValidatorProvider.
Шаблон общего редактора для шага 1 приведен ниже.
@model System.Collections.Generic.IEnumerable<object>
@{
ViewBag.Title = "Collection";
var modelMetadata = this.ViewData.ModelMetadata;
var validators = modelMetadata.GetValidators(ViewContext).ToList();
ViewContext.HttpContext.Items["rootValidators"] = validators;
}
@foreach (var item in Model)
{
@Html.EditorFor(m => item)
}
Вы можете видеть в приведенном выше коде, что мы получаем все валидаторы, указанные в списке. Эти валидаторы будут добавлены к элементам списка позже. Они были сохранены в HttpContext.Items для использования в нашем пользовательском ModelValidatorProvider.
Шаг 2. В Global.asax введите следующий код:
ModelValidatorProviders.Providers.Clear();
ModelValidatorProviders.Providers.Add(new DAModelValidatorProvider());
ModelMetadataProviders.Current = new CachedDataAnnotationsModelMetadataProvider();
Шаг 3. Напишите свой собственный ModelValidatorProvider, переопределив метод GetValidators, как показано в приведенном ниже коде.
public class DAModelValidatorProvider : DataAnnotationsModelValidatorProvider
{
protected override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes)
{
var validators = base.GetValidators(metadata, context, attributes).ToList();
// get root validators of the collection. this was stored in the editor template - fetching it for use now.
// fetching the rootvalidators inside this method is a bad idea because we have to call GetValidators method on the
// containers ModelMetadata and it will result in a non-terminal recursion
var rootValidators = context.HttpContext.Items["rootValidators"] as IEnumerable<ModelValidator>;
if (rootValidators != null)
{
foreach (var rootValidator in rootValidators)
{
validators.Add(rootValidator);
}
}
return validators;
}
}
Выполнение вышеуказанных 3 шагов действительно сработало для меня. Однако я использовал Html.EditorFor вместо Html.TextBoxFor. Используя Html.EditorFor, я не дал мне правильных атрибутов идентификатора и имени - я считаю, что это тривиальная проблема в схеме вещей. Я создал для этого решение и загрузил его на https://github.com/swazza85/Stackoverflow. так что вы можете попробовать и посмотреть, соответствует ли это вашим потребностям. То, что я сделал здесь, ни в коем случае не является полным решением, но, надеюсь, оно поможет вам работать без необходимости менять свои модели.
Привет, Сваруп.
person
swazza85
schedule
02.05.2014
data-val-regex = "MyErrorMessage"
, а неdata-val-required = "MyErrorMessage"
, поскольку у вас нет аннотации[Required]
к вашему ресурсу. - person Bhushan Shah   schedule 02.05.2014