ASP.NET MVC 2 - HTML.EditorFor() and Custom EditorTemplates

23,835

Solution 1

You can either create a custom ViewModel which has both properties OR you'll need to use ViewData to pass that information in.

Solution 2

I am still learning, but I had a similar problem for which I worked out a solution. My Category is an enum and I use a template control which examines the enum to determine the contents for the Select tag.

It is used in the view as:

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

The enum for Category is decorated with Description attributes to be used as the text values in the Select items:

 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; }
        }

The SelectListForEnum constructs the list of select items using the enum definition and the index for the currently selected item, as follows:

        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;
    }

The end result is a nicely presented DDL.

Hope this helps. Any comments about better ways to do this will be greatly appreciated.

Solution 3

Try using ViewData.ModelMetadata this contains all of your class Annotations.

Excellent article http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-4-custom-object-templates.html

Share:
23,835
Nathan Taylor
Author by

Nathan Taylor

I am software developer, primarily web, with experience in ASP.NET MVC, ASP.NET, PHP, Classic ASP, SQL, MySQL, C#, XHTML, CSS, JavaScript, JQuery and more. I have been building websites for about 10 years now, and I love it as much as the day I started. My greatest development philosophy is to strive to build highly functional and interactive applications which surpass expectations and are exciting to use. To see what I'm working on, take a look at my blog or my github. My professional CV can be found at: http://careers.stackoverflow.com/nathantaylor.

Updated on February 02, 2020

Comments

  • Nathan Taylor
    Nathan Taylor over 4 years

    With MVC 2's addition of the HtmlHelper EditorFor() it is not possible to create strongly typed Display and Editor templates for a given Model object and after fiddling with it I am a bit stumped as to how to pass additional Model data to the editor without losing the strong-typing of the editor control.

    Classic Example: Product has Category. ProductEditor has a DropDownList for Category containing the names of all Categories. The ProductEditor is strongly typed to Product and we need to pass in the SelectList of Categories as well as the Product.

    With a standard view we would wrap the Model data in a new type and pass that along. With the EditorTemplate we lose some of the standard functionality if we pass in a mixed Model containing more than one object (first thing I noticed was all of the LabelFor/TextBoxFor methods were producing entity names like "Model.Object" rather than just "Object").

    Am I doing it wrong or should Html.EditorFor() have an additional ViewDataDictionary/Model parameter?

  • Nathan Taylor
    Nathan Taylor almost 15 years
    Naturally this makes sense but I couldn't help but notice that placing the model in a custom ViewModel causes the form field names to be prefixed by the property name of the object in the custom ViewModel. Not that this is a problem but it does add another step to updating the model. I'm probably whining unnecessarily eh?
  • John Farrell
    John Farrell over 14 years
    Thank you so much. I've been looking for this for days now, forgot to bookmark last time I stumbled upon it.