ASP.NET MVC: доступ к атрибутам ViewModel в представлении

Есть ли способ получить доступ к каким-либо атрибутам (будь то атрибуты аннотации данных, атрибуты проверки или настраиваемые атрибуты) свойств ViewModel из представления? Я хотел бы добавить небольшой обязательный индикатор рядом с полями, свойство которых имеет атрибут [Required].

Например, если моя ViewModel выглядела так:

public class MyViewModel
{
    [Required]
    public int MyRequiredField { get; set; } 
}

Я бы хотел сделать что-нибудь в шаблоне EditorFor вот так:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<int?>" %>

<div class="label-container">
    <%: Html.Label("") %>

    <% if (PROPERTY_HAS_REQUIRED_ATTRIBUTE) { %>
        <span class="required">*</span>
    <% } %>
</div>
<div class="field-container">
    <%: Html.TextBox("") %>
    <%: Html.ValidationMessage("") %>
</div>

person ajbeaven    schedule 21.09.2011    source источник


Ответы (2)


Информация, которую вы ищете, находится в ViewData.ModelMetadata. Серия серии сообщений в блоге Брэда Уилсона о шаблонах должен все это объяснить, особенно сообщение на ModelMetadata.

Что касается других атрибутов ValidationAttributes, вы можете получить к ним доступ через _ 2_ метод.

ModelMetadata.IsRequired сообщит вам, требуется ли для RequiredAttribute сложный тип (или тип значения, заключенный в Nullable<T>), но он даст вам ложные срабатывания для типов значений, которые не допускают значения NULL (поскольку они неявно требуются). Вы можете обойти это следующим образом:

bool isReallyRequired = metadata.IsRequired 
    && (!metadata.ModelType.IsValueType || metadata.IsNullableValueType);

Примечание: вам нужно использовать !metadata.ModelType.IsValueType вместо model.IsComplexType, потому что ModelMetadata.IsComplexType возвращает false, поскольку MVC не считается сложным типом, который включает строки.

person Bennor McCarthy    schedule 22.09.2011
comment
А как насчет атрибутов проверки, таких как требования к EditorFor, указанные выше? В этом сообщении в блоге Брэд говорит, что единственными атрибутами, которые влияют на ModelMetadata, являются [HiddenInput], [UIHint], [DataType], [ReadOnly], [DisplayFormat], [ScaffoldColumn] и [DisplayName]. - person ajbeaven; 22.09.2011
comment
Они доступны через метод GetValidators. Я обновил свой ответ, чтобы отразить это. Однако я не уверен в других атрибутах, не связанных с проверкой. - person Bennor McCarthy; 22.09.2011
comment
Другой способ получить информацию об атрибутах - через отражение. например typeof(YourModel).GetProperty("PropertyName").GetCustomAttributes(), но вам определенно не следует делать это в представлении. - person Bennor McCarthy; 22.09.2011

Я бы посоветовал не делать этого, потому что вы добавляете логику в представление, что является плохой практикой. Почему бы вам не создать HtmlHelper или LabelExtension, вы можете вызвать ModelMetaProvider внутри метода и узнать, имеет ли свойство оформленный атрибут Required?

person Van Thoai Nguyen    schedule 22.09.2011
comment
Хороший момент, хотя мой пример выше был упрощен. Мой вопрос больше касается того, как я узнаю, есть ли у свойства требуемый атрибут. Я видел ModelMetaProvider, но его свойство IsRequired не зависит от атрибута [Required]. Все, что мне нужно, это список атрибутов ... - person ajbeaven; 22.09.2011