创建一个使用DropDownListFor等表达式的自定义MVC 3 Helper

时间:2012-02-15 01:05:23

标签: c# asp.net-mvc linq

我想要的HTML输出

<select name="model binding name"> 
 <option value="44" data-object="jsonencoded object">122 front street</option>
 <option value="45" data-object="jsonencoded object">123 main street</option>
<select>

我的cshtml文件中的行看起来像

@Html.DropDownFillerFor(model => model.ProfileAddressId, 
((ProfileUser)ViewData["ProfileData"]).Addresses, 
profileAddress => profileAddress.AddressID.ToString(CultureInfo.InvariantCulture),
profileAddress => profileAddress.House + " " + profileAddress.Street)

该模型类似于商店结帐,您必须从ProfileData中的地址集合中选择要使用的地址。

我的麻烦是理解ViewData如何在帮助程序中工作,我正在阅读MVC 3源代码。

我原来的解决方案是:

public static MvcHtmlString DropDownFillerFor<TModel, TProperty, T2Model>(this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
IEnumerable<T2Model> objectList,
Expression<Func<T2Model, string>> valueExp,
Expression<Func<T2Model, string>> textExp,
IDictionary<string, object> htmlAttributes = null)
        {
 var textFunc = textExp.Compile();
            var valueFunc = valueExp.Compile();
foreach (var o in objectList)
            {
                var sli = new SelectListItem {Text = textFunc(o), Value = valueFunc(o)};
                selectList.Add(sli);
            }
            return htmlHelper.DropDownListFor(expression, selectList, null, null);
}

这很棒但是缺乏基于每个选项添加自定义html属性的能力。 不幸的是DropDownListFor使用的所有方法都是私有的,所以我试图使用他们的代码(假设他们比我更了解这个)。我正在通过SelectExtensions类中的SelectInternal代码工作,我到达了这一行:

object defaultValue = (allowMultiple) ? htmlHelper.GetModelStateValue(fullName, typeof(string[])) : htmlHelper.GetModelStateValue(fullName, typeof(string));

此行似乎从模型中获取值,因此在我的情况下,model =&gt;的值model.ProfileAddressId但我找不到在我的代码中重现这个的方法。

函数GetModelStateValue基本上返回ViewData.ModelState.TryGetValue(key,out modelState)中的值。 Goin在线上更多级别我发现它都引用了“IViewDataContainer ViewDataContainer”。当htmlhelper由“HtmlHelper MakeHtmlHelper(HtmlHelper html,iewDataDictionary viewData)”创建时,它会被填充,我可以上升几个级别,但这是我放松它的地方。

我的问题是。在编写扩展方法时如何从模型中获取值?

1 个答案:

答案 0 :(得分:0)

编辑: 我的解决方案代码发布在http://pastebin.com/r912xtat这已经很长时间了,所以我不记得细节,但是我可以尝试帮助。