Створіть URL-адресу в HTML-помічнику


168

Зазвичай в режимі перегляду ASP.NET можна використовувати таку функцію, щоб отримати URL-адресу (не an <a>):

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

Однак я не можу знайти, як це зробити від користувацького помічника HTML. У мене є

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

Хелперна змінна має методи Action та GenerateLink, але вони генерують <a>s. Я кілька копав вихідний код 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-адреси на зразок цього методу розширення помічника html:

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

2
Я думаю, що було б краще, якщо конструктор також ініціалізує RouteCollectionnew UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection)
kpull1,

22

Ви також можете отримати посилання за допомогою UrlHelperзагальнодоступного та статичного класу:

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

У цьому прикладі не потрібно створювати новий клас UrlHelper, що може бути невеликою перевагою.


Мені подобається ця відповідь більше, тому що встановлює RouteCollection.
kpull1

10

Ось мій крихітний метод 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 Вельд
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.