URL im HTML-Helfer generieren

168

Normalerweise kann man in einer ASP.NET-Ansicht die folgende Funktion verwenden, um eine URL (keine <a>) zu erhalten:

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

Ich kann jedoch nicht herausfinden, wie es mit einem benutzerdefinierten HTML-Helfer geht. ich habe

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

Die Hilfsvariable verfügt über die Methoden Action und GenerateLink, generiert jedoch die Methoden <a>. Ich habe im ASP.NET MVC-Quellcode etwas gegraben, konnte aber keinen einfachen Weg finden.

Das Problem ist, dass die obige URL ein Mitglied der Ansichtsklasse ist und für ihre Instanziierung einige Kontexte und Routenkarten benötigt (mit denen ich mich nicht befassen möchte und die ich sowieso nicht tun soll). Alternativ hat die Instanz der HtmlHelper-Klasse auch einen Kontext, von dem ich annehme, dass er entweder eine Teilmenge der Kontextinformationen der Url-Instanz enthält (aber ich möchte mich auch hier nicht damit befassen).

Zusammenfassend denke ich, dass es möglich ist, aber da alle Möglichkeiten, die ich sehen konnte, einige Manipulationen mit mehr oder weniger internen ASP.NET-Dingen beinhalten, frage ich mich, ob es einen besseren Weg gibt.

Bearbeiten: Eine Möglichkeit, die ich sehe, wäre zum Beispiel:

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

Aber es scheint nicht richtig. Ich möchte mich nicht selbst mit Instanzen von UrlHelper befassen. Es muss einen einfacheren Weg geben.

Jan Zich
quelle
3
Mir ist klar, dass dies ein vereinfachtes Beispiel ist, aber für das gezeigte Beispiel würde ich UrlHelper anstelle von HtmlHelper erweitern. Ihr echter Code benötigt jedoch möglicherweise beides.
Craig Stuntz
Entschuldigung, ich hätte klarer sein sollen: Ich wollte ein HTML-Rendeting in der Erweiterungsmethode durchführen und musste URLs dafür generieren.
Jan Zich

Antworten:

217

Sie können einen URL-Helfer wie diesen in der HTML-Helfer-Erweiterungsmethode erstellen:

var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);
var url = urlHelper.Action("Home", "Index")
Darin Dimitrov
quelle
2
Ich denke, dass es besser wäre, wenn der Konstruktor auch RouteCollectionnew UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection)
kpull1
22

Sie können Links auch mit UrlHelperöffentlichen und statischen Klassen abrufen:

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

In diesem Beispiel müssen Sie keine neue UrlHelper-Klasse erstellen, was ein kleiner Vorteil sein könnte.

Cryss
quelle
Ich mag diese Antwort mehr, weil sie die RouteCollection festlegt.
kpull1
10

Hier ist meine winzige Erweiterungsmethode zum Abrufen UrlHelpereiner HtmlHelperInstanz:

  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];
        }
    }

Verwenden Sie es als:

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

(Ich poste diese Ans nur als Referenz)

Kibria
quelle
Hervorragender Ansatz, da ein vorhandenes Objekt wiederverwendet wird, anstatt ein neues zu erstellen.
Mike
Wir verwenden ASP.NET 4.5 und hatten Probleme beim Wiedereintritt. Wir glauben nicht, dass UrlHelper für http-Anfragen wiederverwendbar ist. Bitte beachten Sie.
Carl in 't Veld