使用ASP.NET MVC在RAZOR中使用带有扩展方法的ViewBag

时间:2013-02-18 14:52:34

标签: razor asp.net-mvc-4 extension-methods

我正在通过学​​习ASP.NET MVC来跋涉。我最近写了一个扩展方法,帮助我决定是否应该选择下拉列表中的项目。我知道HTML帮助器方法。我只是想了解这里的工作原理。无论如何,我目前有以下代码:

<select id="Gender">
  <option value="-1" @Html.IsSelected(Convert.ToString(ViewBag.Gender), "-1")>Unspecified</option>
  <option value="0" @Html.IsSelected(Convert.ToString(ViewBag.Gender), "0")>Male</option>
  <option value="1" @Html.IsSelected(Convert.ToString(ViewBag.Gender), "1")>Female</option>
</select>

当我执行此操作时,我在视图上遇到编译错误:

 CS1973: 'System.Web.Mvc.HtmlHelper<dynamic>' has no applicable method named 'IsSelected' but appears to have an extension method by that name. Extension methods cannot be dynamically dispatched. Consider casting the dynamic arguments or calling the extension method without the extension method syntax.

我的问题是,如何使用ViewBag中的值执行扩展方法?如果我用一个硬编码的值替换ViewBag.Gender它可以工作。这让我觉得问题在于ViewBag是一种动态类型。但是,我还有其他选择吗?

2 个答案:

答案 0 :(得分:0)

这可能有所帮助:

public static class HtmlHelperExtensions
    {
public static MvcHtmlString GenderDropDownList(this HtmlHelper html, string name, int selectedValue, object htmlAttributes = null)
        {
            var dictionary = new Dictionary<sbyte, string>
            {
                { -1, "Unspecified" },
                { 0, "Male" },
                { 1, "Female" },
            };

            var selectList = new SelectList(dictionary, "Key", "Value", selectedValue);
            return html.DropDownList(name, selectList, htmlAttributes);
        }

        public static MvcHtmlString GenderDropDownListFor<TModel>(this HtmlHelper<TModel> html, Expression<Func<TModel, bool?>> expression, object htmlAttributes = null)
        {
            var dictionary = new Dictionary<sbyte, string>
            {
                { -1, "Unspecified" },
                { 0, "Male" },
                { 1, "Female" },
            };

            var selectedValue = ModelMetadata.FromLambdaExpression(
                expression, html.ViewData
            ).Model;

            var selectList = new SelectList(dictionary, "Key", "Value", selectedValue);
            return html.DropDownListFor(expression, selectList, htmlAttributes);
        }
}

像这样使用:

@Html.GenderDropDownList("Gender", 0)

或:

@Html.GenderDropDownListFor(m => m.Gender)

答案 1 :(得分:0)

我也有同样的问题。 使用ViewData代替.. 例如,替换

 @using (Html.BeginSection(tag:"header", htmlAttributes:@ViewBag.HeaderAttributes)) {}

@using (Html.BeginSection(tag:"header", htmlAttributes:@ViewData["HeaderAttributes"])) {}

它工作正常;)