System.Web.mvc.HtmlHelper не содержит определения для EnumDropDownListFor

Я выполнял этот учебник http://blogs.msdn.com/b/stuartleeks/archive/2010/05/21/asp-net-mvc-creating-a-dropdownlist-helper-for-enums.aspx, но я столкнулся с ошибкой "System.Web.Mvc.HtmlHelper не содержит определения для EnumDropDownListFor".

Модель:

public enum Codes
{
    IBC2012,
    IBC2009,
    IBC2006,
    FL2010,
    CBC2007
}

public class Code
{
    public int ID { get; set; }
    public int Active { get; set; }
    public string Description { get; set; }
    public string Edition { get; set; }
    public Codes Code { get; set; }
}

Контроллер:

public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression)
    {
        ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
        IEnumerable<TEnum> values = Enum.GetValues(typeof(TEnum)).Cast<TEnum>();

        IEnumerable<SelectListItem> items =
            values.Select(value => new SelectListItem
            {
                Text = value.ToString(),
                Value = value.ToString(),
                Selected = value.Equals(metadata.Model)
            });

        return htmlHelper.DropDownListFor(
            expression,
            items
            );
    }

HTML-помощник:

@Html.EnumDropDownListFor(model => model.Code.Codes)

Любая помощь приветствуется.

Ответ 1

Вы забыли привнести метод расширения в область видимости внутри представления. Этот метод EnumDropDownListFor определен в некотором статическом классе внутри пространства имен, правильно?

namespace AppName.SomeNamespace
{
    public static class HtmlExtensions
    {
        public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression)
        {
            ...
        }
    }
}

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

@using AppName.SomeNamespace
@model MyViewModel
...
@Html.EnumDropDownListFor(model => model.Code.Codes)

И чтобы не добавлять это предложение использования ко всем вашим представлениям Razor, вы также можете добавить его в раздел <namespaces> вашего файла ~/Views/web.config:

<system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Routing" />
        <add namespace="AppName.SomeNamespace" />
      </namespaces>
    </pages>
</system.web.webPages.razor>

Ответ 2

Измените пространство имен на

namespace System.Web.Mvc
{
    public static class HtmlExtensions
    {
...

Ответ 3

Как @ArhiChief намекнул в ответ, моя проблема:

using System.Web.WebPages.Html;

Вместо:

using System.Web.Mvc;

Оба из них имеют определения для HtmlHelper, поэтому, если вы добавите неверный, вы получите эту ошибку. Заменив его правильным пространством имен, он исправит его.

Ответ 4

В моем случае у меня было пространство имен имен extensions, на которое ссылалось, но отсутствовал оператор using для System.Web.Mvc.Html.

(Методы DropDownList определены в System.Web.Mvc.Html.SelectExtensions)

Ответ 5

Возможно, проблема в том, что ваш HtmlHelper не содержит defination для DropDownList из-за HtmlHelper, определенного в нескольких пространствах имен: System.Web.Mvc и System.Web.WebPages.Html. В пространстве имен System.Web.WebPages.Html содержится HtmlHelper.DropDownList.

Кроме того, не забудьте разместить ваше пространство имен html helper в Views Web.config, поэтому механизм просмотра Razor найдет его.

Ответ 6

Обратите особое внимание в ответе Дарина на то, что вы добавите пространство имен в web.config в папку Views. Не файл web.config в корневой папке. Сначала я этого не заметил, и какое-то время было озадачено, почему это не сработает после добавления моего пространства имен в корневой файл web.config.

Я думаю, это также объясняет, почему он работает для тех, кто меняет свое пространство имен на System.Web.Mvc в своем классе HtmlExtensions. System.Web.Mvc уже включен в пространства имен в файле ~/Views/web.config.

Ответ 7

Как указывалось ранее, правильное пространство имен должно находиться в файле web.config в папке представлений. Пространство имен по умолчанию автоматически включается в файл web.config в папке представлений.

Если пространство имен по умолчанию

 namespace AppName.SomeNamespace

Файл web.config уже содержит запись:

 <add namespace="AppName.SomeNamespace" />

То, о чем не упоминалось ранее, - это когда вы создаете новую папку в своем проекте MVC, пространство имен расширяется. Если вы создали папку под названием Helpers, как и я, то ваше пространство имен для этих методов будет:

 namespace AppName.SomeNamespace.Helpers

Расширенное пространство имен не находится в сети в файле web.config в папке представлений.

У вас есть два варианта:

  • Измените пространство имен в файле с помощью методов html helper на пространство имен по умолчанию, удалив ".Helpers".

  • Добавьте расширенное пространство имен в файл веб-конфигурации

    <add namespace="AppName.SomeNamespace.Helpers">