6.27.2010

MVC 2 DropDownListFor - Any troubles? - Part 1

When working on one project, I have a trouble with MVC DropDownListFor - selected value doesn't returned to the server. I saw a lot of articles, questions, etc.. about this thing. And I decide to write a little article about my solution. As for me - it is more than simple :)

So... using Reflector I take code of SelectExtensions class, and slightly change it:
all methods renamed with suffix "2", to avoid conflicts with MVC's DropDownList
changed 2 lines of code, and added 1 - all changes highlighted on the listing below
Here is a listing:
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Resources;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace HennadiyKurabko.Web.Mvc.Html
{
    /// <summary>Represents support for making selections in a list.</summary>
    public static class SelectExtensions2
    {
        #region Fixed

        /// <summary>Returns a single-selection select element using the specified HTML helper and the name of the form field.</summary>
        /// <returns>An HTML select element.</returns>
        /// <param name="htmlHelper">The HTML helper instance that this method extends.</param>
        /// <param name="name">The name of the form field to return.</param>
        /// <exception cref="T:System.ArgumentException">The <paramref name="name" /> parameter is null or empty.</exception>
        public static MvcHtmlString DropDownList2(this HtmlHelper htmlHelper, string name)
        {
            return htmlHelper.DropDownList2(name, null, null, ((IDictionary<string, object>)null));
        }

        /// <summary>Returns a single-selection select element using the specified HTML helper, the name of the form field, and the specified list items.</summary>
        /// <returns>An HTML select element with an option subelement for each item in the list.</returns>
        /// <param name="htmlHelper">The HTML helper instance that this method extends.</param>
        /// <param name="name">The name of the form field to return.</param>
        /// <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the drop-down list.</param>
        /// <exception cref="T:System.ArgumentException">The <paramref name="name" /> parameter is null or empty.</exception>
        public static MvcHtmlString DropDownList2(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList)
        {
            return htmlHelper.DropDownList2(name, selectList, null, ((IDictionary<string, object>)null));
        }

        /// <summary>Returns a single-selection select element using the specified HTML helper, the name of the form field, and an option label.</summary>
        /// <returns>An HTML select element with an option subelement for each item in the list.</returns>
        /// <param name="htmlHelper">The HTML helper instance that this method extends.</param>
        /// <param name="name">The name of the form field to return.</param>
        /// <param name="optionLabel">The text for a default empty item. This parameter can be null.</param>
        /// <exception cref="T:System.ArgumentException">The <paramref name="name" /> parameter is null or empty.</exception>
        public static MvcHtmlString DropDownList2(this HtmlHelper htmlHelper, string name, string optionLabel)
        {
            return htmlHelper.DropDownList2(name, null, optionLabel, ((IDictionary<string, object>)null));
        }

        /// <summary>Returns a single-selection select element using the specified HTML helper, the name of the form field, the specified list items, and the specified HTML attributes.</summary>
        /// <returns>An HTML select element with an option subelement for each item in the list.</returns>
        /// <param name="htmlHelper">The HTML helper instance that this method extends.</param>
        /// <param name="name">The name of the form field to return.</param>
        /// <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the drop-down list.</param>
        /// <param name="htmlAttributes">An object that contains the HTML attributes to set for the element.</param>
        /// <exception cref="T:System.ArgumentException">The <paramref name="name" /> parameter is null or empty.</exception>
        public static MvcHtmlString DropDownList2(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, IDictionary<string, object> htmlAttributes)
        {
            return htmlHelper.DropDownList2(name, selectList, null, htmlAttributes);
        }

        /// <summary>Returns a single-selection select element using the specified HTML helper, the name of the form field, the specified list items, and the specified HTML attributes.</summary>
        /// <returns>An HTML select element with an option subelement for each item in the list.</returns>
        /// <param name="htmlHelper">The HTML helper instance that this method extends.</param>
        /// <param name="name">The name of the form field to return.</param>
        /// <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the drop-down list.</param>
        /// <param name="htmlAttributes">An object that contains the HTML attributes to set for the element.</param>
        /// <exception cref="T:System.ArgumentException">The <paramref name="name" /> parameter is null or empty.</exception>
        public static MvcHtmlString DropDownList2(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, object htmlAttributes)
        {
            return htmlHelper.DropDownList2(name, selectList, null, ((IDictionary<string, object>)new RouteValueDictionary(htmlAttributes)));
        }

        /// <summary>Returns a single-selection select element using the specified HTML helper, the name of the form field, the specified list items, and an option label.</summary>
        /// <returns>An HTML select element with an option subelement for each item in the list.</returns>
        /// <param name="htmlHelper">The HTML helper instance that this method extends.</param>
        /// <param name="name">The name of the form field to return.</param>
        /// <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the drop-down list.</param>
        /// <param name="optionLabel">The text for a default empty item. This parameter can be null.</param>
        /// <exception cref="T:System.ArgumentException">The <paramref name="name" /> parameter is null or empty.</exception>
        public static MvcHtmlString DropDownList2(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, string optionLabel)
        {
            return htmlHelper.DropDownList2(name, selectList, optionLabel, ((IDictionary<string, object>)null));
        }

        /// <summary>Returns a single-selection select element using the specified HTML helper, the name of the form field, the specified list items, an option label, and the specified HTML attributes.</summary>
        /// <returns>An HTML select element with an option subelement for each item in the list.</returns>
        /// <param name="htmlHelper">The HTML helper instance that this method extends.</param>
        /// <param name="name">The name of the form field to return.</param>
        /// <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the drop-down list.</param>
        /// <param name="optionLabel">The text for a default empty item. This parameter can be null.</param>
        /// <param name="htmlAttributes">An object that contains the HTML attributes to set for the element.</param>
        /// <exception cref="T:System.ArgumentException">The <paramref name="name" /> parameter is null or empty.</exception>
        public static MvcHtmlString DropDownList2(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, string optionLabel, IDictionary<string, object> htmlAttributes)
        {
            return DropDownList2Helper(htmlHelper, name, selectList, optionLabel, htmlAttributes);
        }

        /// <summary>Returns a single-selection select element using the specified HTML helper, the name of the form field, the specified list items, an option label, and the specified HTML attributes.</summary>
        /// <returns>An HTML select element with an option subelement for each item in the list.</returns>
        /// <param name="htmlHelper">The HTML helper instance that this method extends.</param>
        /// <param name="name">The name of the form field to return.</param>
        /// <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the drop-down list.</param>
        /// <param name="optionLabel">The text for a default empty item. This parameter can be null.</param>
        /// <param name="htmlAttributes">An object that contains the HTML attributes to set for the element.</param>
        /// <exception cref="T:System.ArgumentException">The <paramref name="name" /> parameter is null or empty.</exception>
        public static MvcHtmlString DropDownList2(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, string optionLabel, object htmlAttributes)
        {
            return htmlHelper.DropDownList2(name, selectList, optionLabel, ((IDictionary<string, object>)new RouteValueDictionary(htmlAttributes)));
        }

        /// <summary>Returns an HTML select element for each property in the object that is represented by the specified expression using the specified list items.</summary>
        /// <returns>An HTML select element for each property in the object that is represented by the expression.</returns>
        /// <param name="htmlHelper">The HTML helper instance that this method extends.</param>
        /// <param name="expression">An expression that identifies the object that contains the properties to render.</param>
        /// <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the drop-down list.</param>
        /// <typeparam name="TModel">The type of the model.</typeparam>
        /// <typeparam name="TProperty">The type of the value.</typeparam>
        /// <exception cref="T:System.ArgumentNullException">The <paramref name="expression" /> parameter is null.</exception>
        public static MvcHtmlString DropDownList2For<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList)
        {
            return htmlHelper.DropDownList2For<TModel, TProperty>(expression, selectList, null, ((IDictionary<string, object>)null));
        }

        /// <summary>Returns an HTML select element for each property in the object that is represented by the specified expression using the specified list items and HTML attributes.</summary>
        /// <returns>An HTML select element for each property in the object that is represented by the expression.</returns>
        /// <param name="htmlHelper">The HTML helper instance that this method extends.</param>
        /// <param name="expression">An expression that identifies the object that contains the properties to render.</param>
        /// <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the drop-down list.</param>
        /// <param name="htmlAttributes">A dictionary that contains the HTML attributes to set for the element.</param>
        /// <typeparam name="TModel">The type of the model.</typeparam>
        /// <typeparam name="TProperty">The type of the value.</typeparam>
        /// <exception cref="T:System.ArgumentNullException">The <paramref name="expression" /> parameter is null.</exception>
        public static MvcHtmlString DropDownList2For<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, IDictionary<string, object> htmlAttributes)
        {
            return htmlHelper.DropDownList2For<TModel, TProperty>(expression, selectList, null, htmlAttributes);
        }

        /// <summary>Returns an HTML select element for each property in the object that is represented by the specified expression using the specified list items and HTML attributes.</summary>
        /// <returns>An HTML select element for each property in the object that is represented by the expression.</returns>
        /// <param name="htmlHelper">The HTML helper instance that this method extends.</param>
        /// <param name="expression">An expression that identifies the object that contains the properties to render.</param>
        /// <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the drop-down list.</param>
        /// <param name="htmlAttributes">An object that contains the HTML attributes to set for the element.</param>
        /// <typeparam name="TModel">The type of the model.</typeparam>
        /// <typeparam name="TProperty">The type of the value.</typeparam>
        /// <exception cref="T:System.ArgumentNullException">The <paramref name="expression" /> parameter is null.</exception>
        public static MvcHtmlString DropDownList2For<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, object htmlAttributes)
        {
            return htmlHelper.DropDownList2For<TModel, TProperty>(expression, selectList, null, ((IDictionary<string, object>)new RouteValueDictionary(htmlAttributes)));
        }

        /// <summary>Returns an HTML select element for each property in the object that is represented by the specified expression using the specified list items and option label.</summary>
        /// <returns>An HTML select element for each property in the object that is represented by the expression.</returns>
        /// <param name="htmlHelper">The HTML helper instance that this method extends.</param>
        /// <param name="expression">An expression that identifies the object that contains the properties to render.</param>
        /// <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the drop-down list.</param>
        /// <param name="optionLabel">The text for a default empty item. This parameter can be null.</param>
        /// <typeparam name="TModel">The type of the model.</typeparam>
        /// <typeparam name="TProperty">The type of the value.</typeparam>
        /// <exception cref="T:System.ArgumentNullException">The <paramref name="expression" /> parameter is null.</exception>
        public static MvcHtmlString DropDownList2For<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, string optionLabel)
        {
            return htmlHelper.DropDownList2For<TModel, TProperty>(expression, selectList, optionLabel, ((IDictionary<string, object>)null));
        }

        /// <summary>Returns an HTML select element for each property in the object that is represented by the specified expression using the specified list items, option label, and HTML attributes.</summary>
        /// <returns>An HTML select element for each property in the object that is represented by the expression.</returns>
        /// <param name="htmlHelper">The HTML helper instance that this method extends.</param>
        /// <param name="expression">An expression that identifies the object that contains the properties to render.</param>
        /// <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the drop-down list.</param>
        /// <param name="optionLabel">The text for a default empty item. This parameter can be null.</param>
        /// <param name="htmlAttributes">A dictionary that contains the HTML attributes to set for the element.</param>
        /// <typeparam name="TModel">The type of the model.</typeparam>
        /// <typeparam name="TProperty">The type of the value.</typeparam>
        /// <exception cref="T:System.ArgumentNullException">The <paramref name="expression" /> parameter is null.</exception>
        public static MvcHtmlString DropDownList2For<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, string optionLabel, IDictionary<string, object> htmlAttributes)
        {
            if (expression == null)
            {
                throw new ArgumentNullException("expression");
            }
            return DropDownList2Helper(htmlHelper, ExpressionHelper.GetExpressionText(expression), selectList, optionLabel, htmlAttributes);
        }

        /// <summary>Returns an HTML select element for each property in the object that is represented by the specified expression using the specified list items, option label, and HTML attributes.</summary>
        /// <returns>An HTML select element for each property in the object that is represented by the expression.</returns>
        /// <param name="htmlHelper">The HTML helper instance that this method extends.</param>
        /// <param name="expression">An expression that identifies the object that contains the properties to render.</param>
        /// <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the drop-down list.</param>
        /// <param name="optionLabel">The text for a default empty item. This parameter can be null.</param>
        /// <param name="htmlAttributes">An object that contains the HTML attributes to set for the element.</param>
        /// <typeparam name="TModel">The type of the model.</typeparam>
        /// <typeparam name="TProperty">The type of the value.</typeparam>
        public static MvcHtmlString DropDownList2For<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, string optionLabel, object htmlAttributes)
        {
            return htmlHelper.DropDownList2For<TModel, TProperty>(expression, selectList, optionLabel, ((IDictionary<string, object>)new RouteValueDictionary(htmlAttributes)));
        }

        /// <summary>Returns a multi-select select element using the specified HTML helper and the name of the form field.</summary>
        /// <returns>An HTML select element.</returns>
        /// <param name="htmlHelper">The HTML helper instance that this method extends.</param>
        /// <param name="name">The name of the form field to return.</param>
        /// <exception cref="T:System.ArgumentException">The <paramref name="name" /> parameter is null or empty.</exception>
        public static MvcHtmlString ListBox2(this HtmlHelper htmlHelper, string name)
        {
            return htmlHelper.ListBox2(name, null, ((IDictionary<string, object>)null));
        }

        /// <summary>Returns a multi-select select element using the specified HTML helper, the name of the form field, and the specified list items.</summary>
        /// <returns>An HTML select element with an option subelement for each item in the list.</returns>
        /// <param name="htmlHelper">The HTML helper instance that this method extends.</param>
        /// <param name="name">The name of the form field to return.</param>
        /// <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the drop-down list.</param>
        /// <exception cref="T:System.ArgumentException">The <paramref name="name" /> parameter is null or empty.</exception>
        public static MvcHtmlString ListBox2(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList)
        {
            return htmlHelper.ListBox2(name, selectList, ((IDictionary<string, object>)null));
        }

        /// <summary>Returns a multi-select select element using the specified HTML helper, the name of the form field, the specified list items, and the specified HMTL attributes.</summary>
        /// <returns>An HTML select element with an option subelement for each item in the list..</returns>
        /// <param name="htmlHelper">The HTML helper instance that this method extends.</param>
        /// <param name="name">The name of the form field to return.</param>
        /// <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the drop-down list.</param>
        /// <param name="htmlAttributes">An object that contains the HTML attributes to set for the element.</param>
        /// <exception cref="T:System.ArgumentException">The <paramref name="name" /> parameter is null or empty.</exception>
        public static MvcHtmlString ListBox2(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, IDictionary<string, object> htmlAttributes)
        {
            return ListBox2Helper(htmlHelper, name, selectList, htmlAttributes);
        }

        /// <summary>Returns a multi-select select element using the specified HTML helper, the name of the form field, and the specified list items.</summary>
        /// <returns>An HTML select element with an option subelement for each item in the list..</returns>
        /// <param name="htmlHelper">The HTML helper instance that this method extends.</param>
        /// <param name="name">The name of the form field to return.</param>
        /// <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the drop-down list.</param>
        /// <param name="htmlAttributes">An object that contains the HTML attributes to set for the element.</param>
        /// <exception cref="T:System.ArgumentException">The <paramref name="name" /> parameter is null or empty.</exception>
        public static MvcHtmlString ListBox2(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, object htmlAttributes)
        {
            return htmlHelper.ListBox2(name, selectList, ((IDictionary<string, object>)new RouteValueDictionary(htmlAttributes)));
        }

        /// <summary>Returns an HTML select element for each property in the object that is represented by the specified expression and using the specified list items.</summary>
        /// <returns>An HTML select element for each property in the object that is represented by the expression.</returns>
        /// <param name="htmlHelper">The HTML helper instance that this method extends.</param>
        /// <param name="expression">An expression that identifies the object that contains the properties to render.</param>
        /// <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the list.</param>
        /// <typeparam name="TModel">The type of the model.</typeparam>
        /// <typeparam name="TProperty">The type of the value.</typeparam>
        /// <exception cref="T:System.ArgumentNullException">The <paramref name="expression" /> parameter is null.</exception>
        public static MvcHtmlString ListBox2For<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList)
        {
            return htmlHelper.ListBox2For<TModel, TProperty>(expression, selectList, ((IDictionary<string, object>)null));
        }

        /// <summary>Returns an HTML select element for each property in the object that is represented by the specified expression using the specified list items and HTML attributes.</summary>
        /// <returns>An HTML select element for each property in the object that is represented by the expression.</returns>
        /// <param name="htmlHelper">The HTML helper instance that this method extends.</param>
        /// <param name="expression">An expression that identifies the object that contains the properties to render.</param>
        /// <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the list.</param>
        /// <param name="htmlAttributes">A dictionary that contains the HTML attributes to set for the element.</param>
        /// <typeparam name="TModel">The type of the model.</typeparam>
        /// <typeparam name="TProperty">The type of the value.</typeparam>
        /// <exception cref="T:System.ArgumentNullException">The <paramref name="expression" /> parameter is null.</exception>
        public static MvcHtmlString ListBox2For<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, IDictionary<string, object> htmlAttributes)
        {
            if (expression == null)
            {
                throw new ArgumentNullException("expression");
            }
            return ListBox2Helper(htmlHelper, ExpressionHelper.GetExpressionText(expression), selectList, htmlAttributes);
        }

        /// <summary>Returns an HTML select element for each property in the object that is represented by the specified expression using the specified list items and HTML attributes.</summary>
        /// <returns>An HTML select element for each property in the object that is represented by the expression.</returns>
        /// <param name="htmlHelper">The HTML helper instance that this method extends.</param>
        /// <param name="expression">An expression that identifies the object that contains the properties to render.</param>
        /// <param name="selectList">A collection of <see cref="T:System.Web.Mvc.SelectListItem" /> objects that are used to populate the list.</param>
        /// <param name="htmlAttributes">An object that contains the HTML attributes to set for the element.</param>
        /// <typeparam name="TModel">The type of the model.</typeparam>
        /// <typeparam name="TProperty">The type of the value.</typeparam>
        /// <exception cref="T:System.ArgumentNullException">The <paramref name="expression" /> parameter is null.</exception>
        public static MvcHtmlString ListBox2For<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, object htmlAttributes)
        {
            return htmlHelper.ListBox2For<TModel, TProperty>(expression, selectList, ((IDictionary<string, object>)new RouteValueDictionary(htmlAttributes)));
        }

        internal static string ListItemToOption(SelectListItem item)
        {
            TagBuilder builder2 = new TagBuilder("option");
            builder2.InnerHtml = HttpUtility.HtmlEncode(item.Text);
            TagBuilder builder = builder2;
            if (item.Value != null)
            {
                builder.Attributes["value"] = item.Value;
            }
            if (item.Selected)
            {
                builder.Attributes["selected"] = "selected";
            }
            return builder.ToString(TagRenderMode.Normal);
        }

        private static MvcHtmlString ListBox2Helper(HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, IDictionary<string, object> htmlAttributes)
        {
            return htmlHelper.SelectInternal(null, name, selectList, true, htmlAttributes);
        }

        private static MvcHtmlString DropDownList2Helper(HtmlHelper htmlHelper, string expression, IEnumerable<SelectListItem> selectList, string optionLabel, IDictionary<string, object> htmlAttributes)
        {
            return htmlHelper.SelectInternal(optionLabel, expression, selectList, false, htmlAttributes);
        }

        private static IEnumerable<SelectListItem> GetSelectData(this HtmlHelper htmlHelper, string name)
        {
            object obj2 = null;
            if (htmlHelper.ViewData != null)
            {
                obj2 = htmlHelper.ViewData.Eval(name);
            }
            if (obj2 == null)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, MvcResources.HtmlHelper_MissingSelectData, new object[] { name, "IEnumerable<SelectListItem>" }));
            }
            IEnumerable<SelectListItem> enumerable = obj2 as IEnumerable<SelectListItem>;
            if (enumerable == null)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, MvcResources.HtmlHelper_WrongSelectDataType, new object[] { name, obj2.GetType().FullName, "IEnumerable<SelectListItem>" }));
            }
            return enumerable;
        }

        private static MvcHtmlString SelectInternal(this HtmlHelper htmlHelper, string optionLabel, string name, IEnumerable<SelectListItem> selectList, bool allowMultiple, IDictionary<string, object> htmlAttributes)
        {
            ModelState state;
            string shortName = name; // added
            name = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "name");
            }
            bool flag = false;
            if (selectList == null)
            {
                // changed
                // selectList = htmlHelper.GetSelectData(name);
                selectList = htmlHelper.GetSelectData(shortName);
                flag = true;
            }
            object obj2 = allowMultiple ? htmlHelper.GetModelStateValue(name, typeof(string[])) : htmlHelper.GetModelStateValue(name, typeof(string));
            if (!flag && (obj2 == null))
            {
                // changed
                // obj2 = htmlHelper.ViewData.Eval(name);
                obj2 = htmlHelper.ViewData.Eval(shortName);
            }
            if (obj2 != null)
            {
                IEnumerable source = allowMultiple ? (obj2 as IEnumerable) : ((IEnumerable)new object[] { obj2 });
                HashSet<string> set = new HashSet<string>(source.Cast<object>().Select<object, string>(delegate(object value)
                {
                    return Convert.ToString(value, CultureInfo.CurrentCulture);
                }), StringComparer.OrdinalIgnoreCase);
                List<SelectListItem> list = new List<SelectListItem>();
                foreach (SelectListItem item in selectList)
                {
                    item.Selected = (item.Value != null) ? set.Contains(item.Value) : set.Contains(item.Text);
                    list.Add(item);
                }
                selectList = list;
            }
            StringBuilder builder = new StringBuilder();
            if (optionLabel != null)
            {
                SelectListItem item2 = new SelectListItem();
                item2.Text = optionLabel;
                item2.Value = string.Empty;
                item2.Selected = false;
                builder.AppendLine(ListItemToOption(item2));
            }
            foreach (SelectListItem item3 in selectList)
            {
                builder.AppendLine(ListItemToOption(item3));
            }
            TagBuilder builder3 = new TagBuilder("select");
            builder3.InnerHtml = builder.ToString();
            TagBuilder builder2 = builder3;
            builder2.MergeAttributes<string, object>(htmlAttributes);
            builder2.MergeAttribute("name", name, true);
            builder2.GenerateId(name);
            if (allowMultiple)
            {
                builder2.MergeAttribute("multiple", "multiple");
            }
            if (htmlHelper.ViewData.ModelState.TryGetValue(name, out state) && (state.Errors.Count > 0))
            {
                builder2.AddCssClass(HtmlHelper.ValidationInputCssClassName);
            }
            return builder2.ToMvcHtmlString(TagRenderMode.Normal);
        }

        #region Common

        private static object GetModelStateValue(this HtmlHelper self, string key, Type destinationType)
        {
            ModelState state;
            if (self.ViewData.ModelState.TryGetValue(key, out state) && (state.Value != null))
            {
                return state.Value.ConvertTo(destinationType, null);
            }
            return null;
        }

        private static MvcHtmlString ToMvcHtmlString(this TagBuilder self, TagRenderMode renderMode)
        {
            return MvcHtmlString.Create(self.ToString(renderMode));
        }

        private static class MvcResources
        {
            private static CultureInfo resourceCulture;
            private static ResourceManager resourceMan;

            [EditorBrowsable(EditorBrowsableState.Advanced)]
            internal static CultureInfo Culture
            {
                get
                {
                    return resourceCulture;
                }
                set
                {
                    resourceCulture = value;
                }
            }

            [EditorBrowsable(EditorBrowsableState.Advanced)]
            internal static ResourceManager ResourceManager
            {
                get
                {
                    if (object.ReferenceEquals(resourceMan, null))
                    {
                        Assembly mvcAssembly = Assembly.Load("System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
                        ResourceManager manager = new ResourceManager("System.Web.Mvc.Resources.MvcResources", mvcAssembly);
                        resourceMan = manager;
                    }
                    return resourceMan;
                }
            }

            internal static string Common_NullOrEmpty
            {
                get
                {
                    return ResourceManager.GetString("Common_NullOrEmpty", resourceCulture);
                }
            }

            internal static string HtmlHelper_MissingSelectData
            {
                get
                {
                    return ResourceManager.GetString("HtmlHelper_MissingSelectData", resourceCulture);
                }
            }

            internal static string HtmlHelper_WrongSelectDataType
            {
                get
                {
                    return ResourceManager.GetString("HtmlHelper_WrongSelectDataType", resourceCulture);
                }
            }
        }

        #endregion
    }
}
Thats it... When, in MVC 3, will be DropDownList that will work fine you can simply remove suffix "2".

Also.. use it on your own risk ;)


Shout it

kick it on DotNetKicks.com

2 comments:

  1. I was confused at first, then realised you meant a *suffix* 2, not prefix! :-)

    ReplyDelete
  2. Ooops.. what a stupid mistake. Thank you, it was fixed.

    ReplyDelete