Генерация 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, что может быть небольшим преимуществом.

Cryss
источник
Мне нравится этот ответ больше, потому что устанавливает 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');
    //...
}

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

Kibria
источник
Отличный подход, потому что он повторно использует существующий объект, а не создает новый.
Майк
Мы используем ASP.NET 4.5 и испытываем проблемы с повторным входом. Мы не верим, что UrlHelper можно повторно использовать в http-запросах. Пожалуйста, обратите внимание.
Карл в 't Veld