Comment trouver l'URL absolue d'une action dans ASP.NET MVC?


239

Je dois faire quelque chose comme ça:

<script type="text/javascript">
    token_url = "http://example.com/your_token_url";
</script>

J'utilise la version bêta de MVC, mais je ne sais pas comment obtenir l'url absolue d'une action. Je voudrais faire quelque chose comme ça:

<%= Url.AbsoluteAction("Action","Controller")) %>

Existe-t-il une méthode d'assistance ou de page pour cela?

Réponses:


480

Cliquez ici pour plus d'informations, mais essentiellement, il n'y a pas besoin de méthodes d'extension. Il est déjà intégré, mais pas de manière très intuitive.

Url.Action("Action", null, null, Request.Url.Scheme);

6
Intéressant, donc si vous spécifiez le protocole, l'URL est absolue
Casebash

24
Cette réponse est la meilleure, de cette façon, Resharper peut toujours valider que l'action et le contrôleur existent. Je suggérerais l'utilisation de Request.Url.Scheme au lieu du http, de cette façon, http et https sont tous deux pris en charge.
Pbirkoff

2
@Pbirkoff, convenez que c'est la meilleure réponse mais vous aimerez peut-être savoir que vous pouvez annoter vos propres méthodes pour que ReSharper sache que les paramètres représentent des actions / contrôleurs. De cette façon, R # peut toujours valider les chaînes que vous fournissez, comme il le fait si bien.
Drew Noakes

3
Une petite amélioration pourrait être de remplacer "http" par Request.Url.Schemepour que si vous utilisez HTTPS, l'url générée utilisera également HTTPS.
Erik Schierboom

1
Cela fonctionne Html.ActionLinkaussi (toutes les méthodes qui prennent un protocole, les 2 dernières dans MVC 4 par exemple)
Chris

74

Étendre UrlHelper

namespace System.Web.Mvc
{
    public static class HtmlExtensions
    {
        public static string AbsoluteAction(this UrlHelper url, string action, string controller)
        {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;

            string absoluteAction = string.Format(
                "{0}://{1}{2}",
                requestUrl.Scheme,
                requestUrl.Authority,
                url.Action(action, controller));

            return absoluteAction;
        }
    }
}

Alors appelle ça comme ça

<%= Url.AbsoluteAction("Dashboard", "Account")%>

MODIFIER - ANNOTATIONS PLUS RÉDUITES

Le commentaire le plus voté sur la réponse acceptée est This answer is the better one, this way Resharper can still validate that the Action and Controller exists.donc voici un exemple comment vous pourriez obtenir le même comportement.

using JetBrains.Annotations

namespace System.Web.Mvc
{
    public static class HtmlExtensions
    {
        public static string AbsoluteAction(
            this UrlHelper url,
            [AspMvcAction]
            string action,
            [AspMvcController]
            string controller)
        {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;

            string absoluteAction = string.Format(
                "{0}://{1}{2}",
                requestUrl.Scheme,
                requestUrl.Authority,
                url.Action(action, controller));

            return absoluteAction;
        }
    }
}

Informations complémentaires:


3
J'ajouterais également des paramètres facultatifs pour cette solution. Cela devrait couvrir tous les cas.
Eugeniu Torica,

Très agréable! J'ai utilisé ce code mais j'ai fait le seul argument relativeUrl pour que l'appelant puisse le créer en utilisant la méthode Url qu'il souhaite (valeurs du routeur, etc.), et votre méthode peut simplement être responsable de la rendre relative. Le mien est donc: AbsoluteUrl (cette URL UrlHelper, chaîne relativeUrl).
Rob Kent

26
<%= Url.Action("About", "Home", null, Request.Url.Scheme) %>
<%= Url.RouteUrl("Default", new { Action = "About" }, Request.Url.Scheme) %>

21

En utilisant la réponse de @Charlino comme guide, j'ai trouvé ceci.

La documentation ASP.NET MVC pour UrlHelper montre que Url.Action renverra une URL complète si un nom d'hôte et un protocole sont transmis. J'ai créé ces assistants pour forcer le nom d'hôte et le protocole à être fournis. Les multiples surcharges reflètent les surcharges pour Url.

using System.Web.Routing;

namespace System.Web.Mvc {
    public static class HtmlExtensions {

        public static string AbsoluteAction(this UrlHelper url, string actionName) {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;
            return url.Action(actionName, null, (RouteValueDictionary)null, 
                              requestUrl.Scheme, null);
        }

        public static string AbsoluteAction(this UrlHelper url, string actionName, 
                                            object routeValues) {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;
            return url.Action(actionName, null, new RouteValueDictionary(routeValues), 
                              requestUrl.Scheme, null);
        }

        public static string AbsoluteAction(this UrlHelper url, string actionName, 
                                            RouteValueDictionary routeValues) {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;
            return url.Action(actionName, null, routeValues, requestUrl.Scheme, null);
        }

        public static string AbsoluteAction(this UrlHelper url, string actionName, 
                                            string controllerName) {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;
            return url.Action(actionName, controllerName, (RouteValueDictionary)null, 
                              requestUrl.Scheme, null);
        }

        public static string AbsoluteAction(this UrlHelper url, string actionName, 
                                            string controllerName, 
                                            object routeValues) {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;
            return url.Action(actionName, controllerName, 
                              new RouteValueDictionary(routeValues), requestUrl.Scheme, 
                              null);
        }

        public static string AbsoluteAction(this UrlHelper url, string actionName, 
                                            string controllerName, 
                                            RouteValueDictionary routeValues) {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;
            return url.Action(actionName, controllerName, routeValues, requestUrl.Scheme, 
                              null);
        }

        public static string AbsoluteAction(this UrlHelper url, string actionName, 
                                            string controllerName, object routeValues, 
                                            string protocol) {
            Uri requestUrl = url.RequestContext.HttpContext.Request.Url;
            return url.Action(actionName, controllerName, 
                              new RouteValueDictionary(routeValues), protocol, null);
        }

    }
}

4
Thx pour le code m'a beaucoup aidé, mais il y a un problème avec cette solution qui survient généralement pendant le développement. Si le site est hébergé sur un port spécifique, les informations sur le port sont incluses dans requestUrl.Authority , comme localhost: 4423 . Pour une raison quelconque, la méthode Action ajoute à nouveau le port. Donc, soit c'est un bogue dans la méthode d'action, soit vous n'êtes pas censé fournir le port ici. Mais laquelle des propriétés disponibles sur la demande est la bonne (DnsSafeHost ou Host)? Eh bien, la solution est plutôt simple: il suffit de fournir null et la méthode Action remplira la bonne valeur.
ntziolis

J'ai mis à jour la réponse pour incorporer la suggestion de @ ntziolis.
Andrew Arnott

3

Je ne sais pas s'il existe une méthode intégrée pour le faire, mais vous pouvez rouler votre propre méthode HtmlHelper.

Quelque chose comme ce qui suit

namespace System.Web.Mvc
{
    public static class HtmlExtensions
    {
        public static string AbsoluteAction(this HtmlHelper html, string actionUrl)
        {
            Uri requestUrl = html.ViewContext.HttpContext.Request.Url;

            string absoluteAction = string.Format("{0}://{1}{2}",
                                                  requestUrl.Scheme,
                                                  requestUrl.Authority,
                                                  actionUrl);

            return absoluteAction;
        }
    }
}

Alors appelle ça comme ça

<%= Html.AbsoluteAction(Url.Action("Dashboard", "Account"))%> »

HTHs, Charles


2

La réponse complète avec arguments serait:

var url = Url.Action("ActionName", "ControllerName", new { id = "arg_value" }, Request.Url.Scheme);

et cela produira une URL absolue


1

Même résultat mais un peu plus propre (pas de concaténation / formatage de chaîne):

public static Uri GetBaseUrl(this UrlHelper url)
{
    Uri contextUri = new Uri(url.RequestContext.HttpContext.Request.Url, url.RequestContext.HttpContext.Request.RawUrl);
    UriBuilder realmUri = new UriBuilder(contextUri) { Path = url.RequestContext.HttpContext.Request.ApplicationPath, Query = null, Fragment = null };
    return realmUri.Uri;
}

public static string ActionAbsolute(this UrlHelper url, string actionName, string controllerName)
{
    return new Uri(GetBaseUrl(url), url.Action(actionName, controllerName)).AbsoluteUri;
}

0

Peut être ça (?):

<%= 
  Request.Url.GetLeftPart(UriPartial.Authority) + 
  Url.Action("Action1", "Controller2", new {param1="bla", param2="blabla" })
%>

0

env: dotnet core version 1.0.4

Url.Action("Join",null, null,Context.Request.IsHttps?"https":"http");
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.