Пользовательские метаданные в сообщениях проверки - PullRequest
2 голосов
/ 05 августа 2011

Я реализовал пользовательский поставщик метаданных, расширяющий AssociatedMetaDataProvider.Первоначальная цель класса состояла в том, чтобы взять имя свойства и превратить его в слова в Паскале.

У меня есть новое требование добавить визуальный индикатор (символ '*') для меток для всех необходимых полейна сайте.Я могу внести это изменение, добавив следующий код к поставщику пользовательских метаданных:

        PropertyInfo property = containerType.GetProperty(propertyName);
        if (property.GetCustomAttributes(typeof(RequiredAttribute), true).Any())
            metadata.DisplayName = "* " + metadata.DisplayName;

Этот код «работает» в том смысле, что он добавляет символ «*» ко всем меткам.Тем не менее, он имеет побочный эффект от добавления символа «*» ко всем сообщениям проверки (например, используемым Html.ValidationMessageFor(x => x.FirstName). В этом случае я бы хотел, чтобы метка была «* Имя» и ошибкасообщение «Поле имени необходимо заполнить.», а не «Поле имени необходимо заполнить».

Существует ли способ добавить символ «*» как часть метаданных дляметки, не влияющие на имя свойства, используемое в сообщениях проверки? В качестве альтернативы, есть ли способ предоставления пользовательских метаданных при создании сообщений проверки?

Ответы [ 3 ]

1 голос
/ 06 августа 2011

Потратив немного больше времени на размышления о проблеме, мне удалось придумать что-то, что, кажется, работает.Однако мне не очень нравится это решение:

        foreach (ValidationAttribute validationAttribute in attributes.Where(x => x is ValidationAttribute))
        {
            if (String.IsNullOrEmpty(validationAttribute.ErrorMessage))
            {
                validationAttribute.ErrorMessage = validationAttribute.FormatErrorMessage(formattedPropertyName);
            }
        }

Этот код выполняется одновременно с кодом в вопросе (как часть метода CreateMetadata в поставщике пользовательских метаданных).Он работает во всех случаях, которые я тестировал, но на самом деле он не предоставляет метаданные поставщику валидации, а скорее форматирует строку ошибки, используя версию имени свойства в регистре Pascal.Это работает с тем, как настроено большинство обычных проверочных сообщений.Тот факт, что он явно устанавливает сообщение об ошибке в атрибутах проверки, кажется неправильным.

Однако я не знаю, что это будет работать как глобальное решение.Это решение «работает», но я надеюсь, что доступно лучшее решение.

0 голосов
/ 17 мая 2018

Я знаю, что это вопрос на 7 лет, но я уже сталкивался с той же проблемой, и в моем случае решение, представленное здесь, не работает.

Ну, это работает, но все мои переводысообщения пропадут.

Вот что я сделал для ASP.NET MVC Core 2:

public class CustomDisplayMetadataProvider : IDisplayMetadataProvider
{
    public void CreateDisplayMetadata(DisplayMetadataProviderContext context)
    {
        if(context.Attributes.OfType<RequiredAttribute>().FirstOrDefault()?.GetType() == typeof(RequiredAttribute))
        {
            var displayName = context.Attributes.OfType<DisplayNameAttribute>().FirstOrDefault()?.DisplayName ?? context.Key.Name;
            context.DisplayMetadata.DisplayName = () =>
            {
                if(new System.Diagnostics.StackTrace(0).GetFrames().Any(f => f.GetMethod().Name == "Validate"))
                {
                    return displayName;
                }
                else
                {
                    return displayName + " *";
                }
            };
        }
    }
}

Идея состоит в том, чтобы проверить, был ли DisplayName вызван методом Validate, чтобы таким образом мы моглине связывайтесь с сообщениями об ошибках, и провайдеры пользовательских сообщений по-прежнему работают.

Это тоже не идеальное решение, но пока работает.

0 голосов
/ 05 августа 2011

В данный момент я разговариваю по телефону, поэтому не пользуйтесь рефлектором или IDE, однако я не думаю, что вы можете сделать это без изменения валидаторов, потому что их поведение заключается в использовании строки формата сообщения об ошибке, передавая то же отображаемое имя, которое вы изменили здесь. Хотя я могу ошибаться (мне нравится ваш подход здесь).

Однако я сделал то, что вы сделали, написав пользовательские шаблоны редактора, которые также передают контроль над HTML в руки веб-разработчика. используя подход метаданных, вы не можете присвоить звездочке, скажем, свой собственный класс для раскраски.

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

Использование Html.LabelFor, за которым следует необязательный блок, если требуется текущая модель, предлагает большую гибкость, я думаю, и я бы предпочел это по сравнению с решением на основе метаданных, поскольку оно также не мешает проверочным сообщениям.

Как я уже сказал, на начальном сомнении я могу ошибаться:)

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