Genera URL nell'helper HTML


168

Normalmente in una vista ASP.NET si può usare la seguente funzione per ottenere un URL (non un <a>):

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

Tuttavia, non riesco a trovare come farlo da un helper HTML personalizzato. io ho

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

La variabile helper ha i metodi Action e GenerateLink, ma generano quelli <a>. Ho fatto qualche ricerca nel codice sorgente ASP.NET MVC, ma non sono riuscito a trovare un modo semplice.

Il problema è che l'URL sopra è un membro della classe di visualizzazione e per la sua istanza ha bisogno di alcuni contesti e mappe di rotte (che non voglio trattare e che comunque non dovrei fare). In alternativa, l'istanza della classe HtmlHelper ha anche un certo contesto che presumo sia una cena del sottoinsieme delle informazioni di contesto dell'istanza Url (ma di nuovo non voglio occuparmene).

In sintesi, penso che sia possibile, ma dato che tutti i modi in cui ho potuto vedere, comportano una manipolazione con alcune cose ASP.NET più o meno interne, mi chiedo se ci sia un modo migliore.

Modifica: ad esempio, una possibilità che vedo sarebbe:

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

Ma non sembra giusto. Non voglio occuparmi delle istanze di UrlHelper da solo. Deve esserci un modo più semplice.


3
Mi rendo conto che questo è un esempio semplificato, ma per l'esempio mostrato estenderei UrlHelper anziché HtmlHelper. Il tuo vero codice potrebbe aver bisogno di entrambi, però.
Craig Stuntz,

Spiacenti, avrei dovuto essere più chiaro: volevo fare un po 'di rendering HTML nel metodo di estensione e avevo bisogno di generare URL per questo.
Jan Zich,

Risposte:


217

Puoi creare l'helper dell'URL in questo modo all'interno del metodo di estensione dell'helt html:

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

2
Penso che sarebbe meglio se il costruttore inizializzasse anche RouteCollectionnew UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection)
kpull1

22

Puoi anche ottenere link usando UrlHelperla classe pubblica e statica:

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

In questo esempio non è necessario creare una nuova classe UrlHelper quale potrebbe essere un piccolo vantaggio.


Mi piace di più questa risposta perché imposta RouteCollection.
kpull1,

10

Ecco il mio piccolo metodo per ottenere extenstion UrlHelperdi un HtmlHelperesempio:

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

Usalo come:

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

(Sto postando questo ans solo come riferimento)


Approccio eccellente perché riutilizza un oggetto esistente anziché crearne uno nuovo.
Mike

Stiamo utilizzando ASP.NET 4.5 e abbiamo riscontrato problemi di rientro. Non crediamo che UrlHelper sia riutilizzabile tra le richieste http. Si prega di notare.
Carl in 't Veld il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.