Генерация URL в HTML помощник


168

Обычно в представлении ASP.NET можно использовать следующую функцию для получения URL (не <a>):

Url.Action("Action", "Controller");

Тем не менее, я не могу найти, как это сделать с помощью специального помощника HTML. у меня есть

public class MyCustomHelper
{
   public static string ExtensionMethod(this HtmlHelper helper)
   {
   }
}

Вспомогательная переменная имеет методы Action и GenerateLink, но они генерируют <a>. Я немного покопался в исходном коде ASP.NET MVC, но не смог найти прямой путь.

Проблема заключается в том, что указанный выше URL-адрес является членом класса представления, и для его реализации ему нужны некоторые контексты и карты маршрутов (с которыми я не хочу иметь дело, и в любом случае я не должен). В качестве альтернативы, экземпляр класса HtmlHelper также имеет некоторый контекст, который, как я предполагаю, является либо ужином подмножества контекстной информации экземпляра Url (но, опять же, я не хочу иметь с этим дело).

Подводя итог, я думаю, что это возможно, но так как все способы, которые я мог видеть, включая некоторые манипуляции с некоторыми более или менее внутренними вещами ASP.NET, я задаюсь вопросом, есть ли лучший способ.

Редактировать: Например, я вижу одну возможность:

public class MyCustomHelper
{
    public static string ExtensionMethod(this HtmlHelper helper)
    {
        UrlHelper urlHelper = new UrlHelper(helper.ViewContext.RequestContext);
        urlHelper.Action("Action", "Controller");
    }
}

Но это не кажется правильным. Я не хочу иметь дело с примерами UrlHelper сам. Должен быть более простой способ.


3
Я понимаю, что это упрощенный пример, но для показанного примера я бы расширил UrlHelper вместо HtmlHelper. Ваш реальный код может потребовать и того, и другого.
— Крейг Штунц,

Извините, мне следовало быть более ясным: я хотел сделать HTML-рендеринг в методе расширения, и мне нужно было сгенерировать URL для него.
— Ян Зич

Ответы:


217

Вы можете создать url helper следующим образом в методе расширения html helper:

var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);
var url = urlHelper.Action("Home", "Index")

2
Я думаю, что было бы лучше, если бы конструктор также инициализировал RouteCollectionnew UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection)
— kpull1

22

Вы также можете получить ссылки, используя UrlHelperpublic и static класс:

UrlHelper.GenerateUrl(null, actionName, controllerName, null, null, null, routeValues, htmlHelper.RouteCollection, htmlHelper.ViewContext.RequestContext, true)

В этом примере вам не нужно создавать новый класс UrlHelper, что может быть небольшим преимуществом.


Мне нравится этот ответ больше, потому что устанавливает RouteCollection.
— kpull1

10

Вот мой крошечный метод extenstion для получения UrlHelperиз HtmlHelperэкземпляра:

  public static partial class UrlHelperExtensions
    {
        /// <summary>
        /// Gets UrlHelper for the HtmlHelper.
        /// </summary>
        /// <param name="htmlHelper">The HTML helper.</param>
        /// <returns></returns>
        public static UrlHelper UrlHelper(this HtmlHelper htmlHelper)
        {
            if (htmlHelper.ViewContext.Controller is Controller)
                return ((Controller)htmlHelper.ViewContext.Controller).Url;

            const string itemKey = "HtmlHelper_UrlHelper";

            if (htmlHelper.ViewContext.HttpContext.Items[itemKey] == null)
                htmlHelper.ViewContext.HttpContext.Items[itemKey] = new UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection);

            return (UrlHelper)htmlHelper.ViewContext.HttpContext.Items[itemKey];
        }
    }

Используйте это как:

public static MvcHtmlString RenderManagePrintLink(this HtmlHelper helper, )
{    
    var url = htmlHelper.UrlHelper().RouteUrl('routeName');
    //...
}

(Я публикую этот ответ только для справки)


Отличный подход, потому что он повторно использует существующий объект, а не создает новый.
— Майк

Мы используем ASP.NET 4.5 и испытываем проблемы с повторным входом. Мы не верим, что UrlHelper можно повторно использовать в http-запросах. Пожалуйста, обратите внимание.
— Карл в 't Veld
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.