Générer une URL dans l'assistance HTML

168

Normalement, dans une vue ASP.NET, on peut utiliser la fonction suivante pour obtenir une URL (pas une <a>):

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

Cependant, je ne trouve pas comment le faire à partir d'un assistant HTML personnalisé. j'ai

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

La variable d'assistance a les méthodes Action et GenerateLink, mais elles génèrent <a>des. J'ai fait quelques recherches dans le code source ASP.NET MVC, mais je n'ai pas pu trouver de moyen simple.

Le problème est que l'URL ci-dessus est membre de la classe de vue et que pour son instanciation, elle a besoin de contextes et de cartes de route (dont je ne veux pas parler et que je ne suis pas censé de toute façon). Alternativement, l'instance de la classe HtmlHelper a également un contexte qui, je suppose, est soit un sous-ensemble des informations de contexte de l'instance Url (mais encore une fois, je ne veux pas m'en occuper).

En résumé, je pense que c'est possible, mais puisque toutes les façons dont je pouvais voir, impliquent une manipulation avec des trucs ASP.NET plus ou moins internes, je me demande s'il existe une meilleure façon.

Edit: Par exemple, une possibilité que je vois serait:

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

Mais cela ne semble pas juste. Je ne veux pas traiter moi-même d'instances d'UrlHelper. Il doit y avoir un moyen plus simple.

Jan Zich
la source
3
Je me rends compte que c'est un exemple simplifié, mais pour l'exemple montré, j'étendrais UrlHelper au lieu de HtmlHelper. Votre vrai code peut cependant avoir besoin des deux.
Craig Stuntz
Désolé, j'aurais dû être plus clair: je voulais faire du rendu HTML dans la méthode d'extension et j'avais besoin de générer des URL pour cela.
Jan Zich

Réponses:

217

Vous pouvez créer un helper url comme ceci dans la méthode d'extension d'assistance html:

var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);
var url = urlHelper.Action("Home", "Index")
Darin Dimitrov
la source
2
Je pense que ce serait mieux si le constructeur initialise également RouteCollectionnew UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection)
kpull1
22

Vous pouvez également obtenir des liens en utilisant UrlHelperla classe publique et statique:

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

Dans cet exemple, vous n'avez pas besoin de créer une nouvelle classe UrlHelper, ce qui pourrait être un petit avantage.

cryss
la source
J'aime plus cette réponse car définit la RouteCollection.
kpull1
10

Voici ma petite méthode d'extension pour obtenir UrlHelperune HtmlHelperinstance:

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

Utilisez-le comme:

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

(Je poste cet article pour référence seulement)

Kibria
la source
Excellente approche car elle réutilise un objet existant plutôt que d'en créer un nouveau.
Mike
Nous utilisons ASP.NET 4.5 et rencontrons des problèmes de réintégration. Nous ne pensons pas qu'UrlHelper soit réutilisable dans les requêtes http. Veuillez prendre note.
Carl in 't Veld le