ASP.NET MVC 2 - HTML.EditorFor () и настраиваемые шаблоны EditorTemplates

С добавлением в MVC 2 HtmlHelper EditorFor () невозможно создавать строго типизированные шаблоны отображения и редактора для данного объекта модели, и после того, как я возился с ним, я немного озадачен тем, как передать дополнительные данные модели в редактор без потери строгая типизация элемента управления редактора.

Классический пример: у товара есть категория. В ProductEditor есть DropDownList для Category, содержащий названия всех категорий. ProductEditor строго типизирован для Product, и нам нужно передать SelectList of Categories, а также Product.

В стандартном представлении мы бы обернули данные модели в новый тип и передали его. С EditorTemplate мы теряем некоторые стандартные функциональные возможности, если передаем смешанную модель, содержащую более одного объекта (первое, что я заметил, это то, что все методы LabelFor / TextBoxFor производили имена сущностей, такие как «Model.Object», а не просто «Object» ").

Я делаю это неправильно или у Html.EditorFor () должен быть дополнительный параметр ViewDataDictionary / Model?


person Nathan Taylor    schedule 05.08.2009    source источник


Ответы (3)


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

person Haacked    schedule 08.08.2009
comment
Естественно, это имеет смысл, но я не мог не заметить, что размещение модели в пользовательской ViewModel приводит к тому, что имена полей формы имеют префикс в виде имени свойства объекта в пользовательской ViewModel. Не то чтобы это проблема, но это добавляет еще один шаг к обновлению модели. Я наверное без надобности ною а? - person Nathan Taylor; 09.08.2009

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

Он используется в представлении как:

<%= Html.DropDownList
            (
            "CategoryCode",
            MvcApplication1.Utility.EditorTemplates.SelectListForEnum(typeof(WebSite.ViewData.Episode.Procedure.Category), selectedItem)
            ) %>

Перечисление для Category украшено атрибутами Description, которые будут использоваться в качестве текстовых значений в элементах Select:

 public enum Category 
        {
            [Description("Operative")]
            Operative=1,
            [Description("Non Operative")]
            NonOperative=2,
            [Description("Therapeutic")]
            Therapeutic=3 
        }
        private Category _CategoryCode; 
        public Category CategoryCode 
        {
            get { return _CategoryCode; }
            set { _CategoryCode = value; }
        }

SelectListForEnum создает список выбранных элементов, используя определение перечисления и индекс для текущего выбранного элемента, как показано ниже:

        public static SelectListItem[] SelectListForEnum(System.Type typeOfEnum, int selectedItem)
    {
        var enumValues = typeOfEnum.GetEnumValues();
        var enumNames = typeOfEnum.GetEnumNames();
        var count = enumNames.Length;
        var enumDescriptions = new string[count];
        int i = 0;
        foreach (var item in enumValues) 
        {
            var name = enumNames[i].Trim();
            var fieldInfo = item.GetType().GetField(name);
            var attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
            enumDescriptions[i] = (attributes.Length > 0) ? attributes[0].Description : name;
            i++;
        }
        var list = new SelectListItem[count];
        for (int index = 0; index < list.Length; index++)
        {
            list[index] = new SelectListItem { Value = enumNames[index], Text = enumDescriptions[index], Selected = (index == (selectedItem - 1)) };
        }
        return list;
    }

Конечный результат - красиво оформленный DDL.

Надеюсь это поможет. Будем очень благодарны за любые комментарии о лучших способах сделать это.

person Graeme    schedule 14.12.2009

Попробуйте использовать ViewData.ModelMetadata, который содержит все аннотации вашего класса.

Отличная статья http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-4-custom-object-templates.html.

person DalSoft    schedule 30.12.2009
comment
Большое спасибо. Я искал это уже несколько дней, забыл сделать закладку в последний раз, когда наткнулся на это. - person John Farrell; 21.01.2010