Атрибуты данных ASP.NET MVC 3 — программная установка UIHint из контроллера

Если у меня есть такая ViewModel:

public class SignupViewModel
{
   [Required]
   [DisplayName("Email:")]
   public string EmailAddress { get; set; }   
}

И используйте EditorFor для отображения полей формы:

@Html.EditorFor(model => model.EmailAddress )

Он будет отображать <input type="text">. Прохладно.

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

Я знаю, что могу использовать [UIHint], но могу ли я сделать это программно с контроллера?

E.g:

var model = new SignupViewModel();
model.EmailAddress = GetFromMysterySource(); // How do i set a UIHint?

Как лучше всего подойти к этому? Должен ли я вообще использовать отдельную ViewModel, что может означать изменение моего представления со строго типизированного на dynamic, или я не должен использовать EditorFor, или я должен использовать собственный шаблон редактора?

Предложения/советы будут весьма признательны.


person RPM1984    schedule 05.04.2011    source источник


Ответы (1)


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

  @if (Model.EmailAddressIsFixed)
  {
     @Html.DisplayFor( m => m.EmailAddress )
     @Html.HiddenFor( m => m.EmailAddress ) // only if you need it to post back
  }
  else
  {
     @Html.EditorFor( m => m.EmailAddress )
  }

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

  @Html.EditorFor( m => m.EmailAddress, 
                   "FixedAddressTemplate",
                   new { Fixed = Model.EmailAddressIsFixed } )
person tvanfosson    schedule 05.04.2011
comment
Как бы я сделал это с шаблоном редактора? Поскольку между EmailAddressIsFixed и EmailAddress нет никакой связи. Я мог бы создать вложенную модель представления, но тогда я не смогу использовать атрибуты данных на уровне родительской модели (например, [Required]). - person RPM1984; 05.04.2011
comment
@RPM — вы можете передать дополнительные данные в шаблон редактора. @Html.EditorFor( m => m.EmailAddress, new { Fixed = Model.EmailAddressIsFixed } ) - person tvanfosson; 05.04.2011
comment
@tvanfossen - до сих пор не могу добавить к нему атрибуты данных. Где разместить атрибут [Required]? Поскольку это больше не поле, например public string EmailAddress { get; set; }, это класс. И я не могу поместить атрибут в поля во внутреннем классе, потому что тогда его нельзя использовать повторно. - person RPM1984; 06.04.2011
comment
@RPM - как насчет того, чтобы не использовать вложенную модель и указать имя шаблона во вспомогательном методе? - person tvanfosson; 06.04.2011
comment
Да, это хорошая идея. Хорошо, вы меня на правильном пути. Принято, спасибо! - person RPM1984; 07.04.2011
comment
Хмм «Вы не можете применить атрибут во время выполнения». Афаик это возможно. Посмотрите здесь dotnetslackers.com/ статьи/аспнет/ - person TweeZz; 25.06.2012
comment
@TweeZz - строго говоря, атрибут не применяется к классу, а скорее изменяет метаданные для модели, предоставленной представлению. Обычно метаданные заполняются из атрибутов, но использование настраиваемого поставщика метаданных позволяет вам дополнить их. В MVC есть и другие хуки, которые позволяют вам также настраивать глобальные фильтры, которые действуют так же, как атрибуты, но они по-прежнему не применяют атрибут к классу во время выполнения. Он использует конвейер фильтрации, предоставляемый платформой. Однако это была бы альтернатива этому методу. - person tvanfosson; 25.06.2012