Подтвердить что ты не робот

Получение полного имени свойства с помощью ModelMetadata

Я пытаюсь создать HtmlHelper, который создаст поля формы, совместимые с Bootstrap. Моя первая цель состояла в том, чтобы создать HtmlHelper, который создаст окружающий div:

<div class="control-group"> ... </div>

Следуя отличным советам здесь, а также здесь, мне удалось заставить его работать относительно быстро. Но это не всегда работает.

У меня есть ViewModel со сложным свойством, поэтому в моей форме я обращаюсь к полю m=>m.Complex.Element. В моем помощнике я проверяю элемент на ошибки проверки. Я использую ModelMetadata.FromLambdaExpression(expression, html.ViewData). Полученные метаданные имеют имя свойства Element, а не Complex.Element.

Когда я проверяю ModelState для этого свойства, я не могу его найти, потому что ModelState сохраняет полное имя - Complex.Element.

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

4b9b3361

Ответ 1

Хорошо, что источники MVC находятся в открытом доступе. Правильный способ получить имя свойства ModelState - с помощью

var propertyName = ExpressionHelper.GetExpressionText(expression);

Ответ 2

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

ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix;

В противном случае вытащите отражатель /ilspy/whatever и проверьте, что делает ваш редактор для TextBoxFor или какой-либо метод, который делает ваш редактор.

Ответ 3

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

public static MvcHtmlString HasErrorClassFor<TModel, TProperty>(
    this HtmlHelper<TModel> htmlHelper,
    Expression<Func<TModel, TProperty>> expression)
{
    string expressionText = ExpressionHelper.GetExpressionText(expression);

    string htmlFieldPrefix = htmlHelper.ViewData.TemplateInfo.HtmlFieldPrefix;

    string fullyQualifiedName;

    if (htmlFieldPrefix.Length > 0)
    {
        fullyQualifiedName = string.Join(".", htmlFieldPrefix, expressionText);
    }
    else
    {
        fullyQualifiedName = expressionText;
    }

    bool isValid = htmlHelper.ViewData.ModelState.IsValidField(fullyQualifiedName);

    if (!isValid)
    {
        return MvcHtmlString.Create("has-error");
    }

    return MvcHtmlString.Empty;
}