Использование расширений MVC HtmlHelper из декларативных представлений Razor - PullRequest
122 голосов
/ 17 января 2011

Я пытался создать декларативный помощник Razor в своей папке App_Code для RTM-проекта MVC 3.

Проблема, с которой я столкнулся, заключалась в том, что расширения MVC HtmlHelper, такие как ActionLink, недоступны.Это связано с тем, что скомпилированные помощники являются производными от System.Web.WebPages.HelperPage и, хотя они предоставляют свойство Html, оно имеет тип System.Web.WebPages.HtmlHelper, а не System.Web.Mvc.HtmlHelper.

Пример ошибки, которую я получалis:

'System.Web.Mvc.HtmlHelper' не содержит определения для ActionLink и нет метода расширения ActionLink, принимающего первый аргумент типа 'System.Web.Mvc.HtmlHelper'может быть найдено (вам не хватает директивы using или ссылки на сборку?)

Мое единственное решение - создать собственный HelperPage и переопределить свойство Html:

using System.Web.WebPages;

public class HelperPage : System.Web.WebPages.HelperPage 
{
    // Workaround - exposes the MVC HtmlHelper instead of the normal helper
    public static new HtmlHelper Html
    {
        get { return ((System.Web.Mvc.WebViewPage) WebPageContext.Current.Page).Html; }
    }
}

Затем я должен написать следующее в верхней части каждого помощника:

@inherits FunnelWeb.Web.App_Code.HelperPage
@using System.Web.Mvc
@using System.Web.Mvc.Html

@helper DoSomething()
{
    @Html.ActionLink("Index", "Home")
}

Это должно быть так сложно в MVC 3, или я делаю что-то не так?

Ответы [ 9 ]

42 голосов
/ 17 января 2011

Посмотрите на ответ Marcind на этот вопрос. То, что вы испытываете, это ограничение размещения декларативных представлений в папке App_Code.

Помещение ваших помощников в App_Code работает но имеет определенные ограничения, которые воздействовать на определенные сценарии MVC (для пример: нет доступа к стандартному MVC Html. хелперы)

38 голосов
/ 05 апреля 2011

Я создал метод расширения для помощника WebPages, чтобы получить доступ к помощнику страницы.

public static HtmlHelper GetPageHelper(this System.Web.WebPages.Html.HtmlHelper html)
{
 return ((System.Web.Mvc.WebViewPage) WebPageContext.Current.Page).Html;
}
11 голосов
/ 17 января 2011

У Омара здесь правильный ответ, но я хотел кое-что добавить (не стесняйтесь помечать ответ Омара как ответ).

Мы знали об этом в v1 и не смогли получить отличное исправление в продукте, но Дэвид Эббо (архитектор из команды ASP.Net) опубликовал пример генератора кода Visual Studio, который по сути является Первое исследование идей, которые мы рассматриваем, чтобы сделать эту работу правильно: http://blogs.msdn.com/b/davidebb/archive/2010/10/27/turn-your-razor-helpers-into-reusable-libraries.aspx

Попробуйте и посмотрите, что вы думаете! Сообщите Дэвиду, если у вас есть комментарии, разместив его в своем блоге.

9 голосов
/ 27 марта 2014

Аналогично ответу @Jakes:

public static class MvcIntrinsics {
    public static System.Web.Mvc.HtmlHelper Html {
        get { return ((System.Web.Mvc.WebViewPage)WebPageContext.Current.Page).Html; }
    }

    public static System.Web.Mvc.AjaxHelper Ajax {
        get { return ((System.Web.Mvc.WebViewPage)WebPageContext.Current.Page).Ajax; }
    }

    public static System.Web.Mvc.UrlHelper Url {
        get { return ((System.Web.Mvc.WebViewPage)WebPageContext.Current.Page).Url; }
    }

}

Использование:

@MvcIntrinsics.Html.Raw("test")

Источник: Дино Эспозито - Программирование Microsoft ASP.NET MVC

7 голосов
/ 17 февраля 2015

Альтернативное решение:

Добавьте это поверх файла вспомогательного файла:

@functions {
    public static System.Web.Mvc.HtmlHelper<object> HHtml = ((System.Web.Mvc.WebViewPage)WebPageContext.Current.Page).Html;
}

, затем назовите это так:

@HHtml.ActionLink("actionname")
4 голосов
/ 25 июля 2012

Для удобства поисковиков я получил ту же ошибку при создании представлений MVC как части библиотеки классов (для повторного использования компонента).Решение, частично упомянутое выше, состояло в том, чтобы добавить следующие операторы использования в начале файла .cshtml:

@using System.Web.Mvc
@using System.Web.Mvc.Html

Дальнейшая работа не требуется.

3 голосов
/ 15 сентября 2015

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

@helper DoSomething(WebViewPage page)
{
    @page.Html.ActionLink("Index", "Home")
}

Тогда в вашем Razor-представлении, где вам это нужно, назовите это так:

@YourHelperFilename.DoSomething(this)

Это немедленно дает вам доступ к таким свойствам страницы, как Html или Url, которые у вас обычно есть (и через это расширения HtmlHelper).

В качестве дополнительного преимущества (если вам это требуется) вы также получаете доступ к свойствам экземпляра, таким как ViewData.

страницы.
0 голосов
/ 28 мая 2014

Похоже, ASP.NET MVC исправил эту проблему в VS 2013. См. Этот пост http://aspnet.uservoice.com/forums/41201-asp-net-mvc/suggestions/3670180-support-helper-extensionmethod-this-htmlhelper-ht

0 голосов
/ 17 января 2011

Я знаю, что с MVC 3 есть некоторые проблемы с intellisense. Я думаю, что помощники будут работать, если у вас есть пространство имен, заданное в web.config.или бета?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...