394 votes

Obtenir l'URL complète d'une action en ASP.NET MVC

Existe-t-il un moyen intégré d'obtenir l'URL complet d'une action ?

Je cherche quelque chose comme GetFullUrl("Action", "Controller") qui renverrait quelque chose comme http://www.fred.com/Controller/Action .

Je cherche à éviter de coder en dur les URL dans les courriels automatisés qui sont générés afin que les URL puissent toujours être générées par rapport à l'emplacement actuel du site.

0 votes

604voto

Paddy Points 16834

Il existe une surcharge de Url.Action qui prend le protocole souhaité (par exemple http, https) comme argument - si vous le spécifiez, vous obtenez une URL entièrement qualifiée.

Voici un exemple qui utilise le protocole de la requête en cours dans une méthode d'action :

var fullUrl = this.Url.Action("Edit", "Posts", new { id = 5 }, this.Request.Url.Scheme);

HtmlHelper (@Html) possède également une surcharge de la méthode ActionLink que vous pouvez utiliser dans razor pour créer un élément d'ancrage, mais elle nécessite également les paramètres hostName et fragment. Je choisirais donc d'utiliser à nouveau @Url.Action :

<span>
  Copy
  <a href='@Url.Action("About", "Home", null, Request.Url.Scheme)'>this link</a> 
  and post it anywhere on the internet!
</span>

7 votes

Pas de problème - on pourrait penser qu'il y a quand même une meilleure façon de faire, mais bon...

0 votes

Lors d'un test local avec l'émulateur Azure, le port 82 est renvoyé au lieu du port 81 correct. Je ne sais pas si cela fonctionne bien en cas de publication ou non. La réponse proposée par Marius Schulz fonctionne parfaitement.

1 votes

La bonne url est https://127.0.0.1/Home/Index mais il génère https://127.0.0.1:444/Home/Index . Il ne doit pas avoir de port. Je fonctionne sur l'émulateur Azure. Veuillez m'aider.

137voto

Marius Schulz Points 5141

Comme Paddy l'a mentionné : si vous utilisez une surcharge de UrlHelper.Action() qui spécifie explicitement le protocole à utiliser, l'URL générée sera absolue et entièrement qualifiée au lieu d'être relative.

J'ai écrit un article de blog intitulé Comment construire des URL d'action absolus à l'aide de la classe UrlHelper dans laquelle je suggère d'écrire une méthode d'extension personnalisée pour des raisons de lisibilité :

/// <summary>
/// Generates a fully qualified URL to an action method by using
/// the specified action name, controller name and route values.
/// </summary>
/// <param name="url">The URL helper.</param>
/// <param name="actionName">The name of the action method.</param>
/// <param name="controllerName">The name of the controller.</param>
/// <param name="routeValues">The route values.</param>
/// <returns>The absolute URL.</returns>
public static string AbsoluteAction(this UrlHelper url,
    string actionName, string controllerName, object routeValues = null)
{
    string scheme = url.RequestContext.HttpContext.Request.Url.Scheme;

    return url.Action(actionName, controllerName, routeValues, scheme);
}

Vous pouvez alors simplement l'utiliser comme cela dans votre vue :

@Url.AbsoluteAction("Action", "Controller")

0 votes

J'aurais aimé que vous ayez plus de votes positifs, c'est une évidence qui devrait figurer dans le cadre de travail.

9 votes

La seule chose que j'ajouterais (ou modifierais) est de remplacer le littéral "http" par HttpContext.Current.Request.Url.Scheme. Cela permettra d'utiliser https lorsque cela est approprié.

0 votes

@Jay, merci pour votre suggestion, j'ai mis à jour mon exemple de code. J'ai reçu le même feedback sur mon billet de blog ;-).

4voto

Salman Zahid Points 161

Voilà ce que vous devez faire.

@Url.Action(action,controller, null, Request.Url.Scheme)

2voto

LIUFA Points 3642

Cette question est spécifique à ASP.NET, mais je suis sûr que certains d'entre vous bénéficient d'un javascript agnostique au système, ce qui est bénéfique dans de nombreuses situations.

UPDATE : La façon d'obtenir une url formée en dehors de la page elle-même est bien décrite dans les réponses ci-dessus.

Ou vous pouvez faire un oneliner comme ceci :

new UrlHelper(actionExecutingContext.RequestContext).Action(
    "SessionTimeout", "Home", 
    new {area = string.Empty}, 
    actionExecutingContext.Request.Url!= null? 
    actionExecutingContext.Request.Url.Scheme : "http"
);

du filtre ou :

new UrlHelper(this.Request.RequestContext).Action(
    "Details", 
    "Journey", 
    new { area = productType }, 
    this.Request.Url!= null? this.Request.Url.Scheme : "http"
);

Cependant, il arrive souvent que l'on ait besoin d'obtenir l'url de la page en cours, pour cela on utilise Html.Action et mettre le nom et le contrôleur de la page dans laquelle vous vous trouvez me semble gênant. Dans ce cas, ma préférence va à l'utilisation de JavaScript. C'est particulièrement bien dans les systèmes qui sont à moitié réécrits MVT, à moitié web-forms, à moitié vb-script, à moitié Dieu sait quoi - et pour obtenir l'URL de la page actuelle, il faut utiliser une méthode différente à chaque fois.

Une façon d'utiliser JavaScript pour obtenir l'URL est la suivante window.location.href un autre - document.URL

1voto

Matt D Points 1825

J'avais un problème avec ça, mon serveur fonctionnait derrière un équilibreur de charge. L'équilibreur de charge mettait fin à la connexion SSL/TLS. Il transmettait ensuite la requête aux serveurs web en utilisant http.

En utilisant la méthode Url.Action() avec Request.Url.Schema, il a continué à créer une url http, dans mon cas pour créer un lien dans un e-mail automatisé (ce que mon PenTester n'a pas aimé).

J'ai peut-être un peu triché, mais c'est exactement ce dont j'avais besoin pour forcer une url https :

<a href="@Url.Action("Action", "Controller", new { id = Model.Id }, "https")">Click Here</a>

J'utilise en fait un AppSetting web.config pour pouvoir utiliser http lors du débogage local, mais tous les environnements de test et de production utilisent la transformation pour définir la valeur https.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X