Wie finde ich die absolute URL einer Aktion in ASP.NET MVC?

239

Ich muss so etwas tun:

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

Ich verwende die Beta-Version von MVC, kann aber nicht herausfinden, wie ich die absolute URL einer Aktion erhalte. Ich möchte so etwas machen:

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

Gibt es dafür einen Helfer oder eine Page-Methode?

Mike Comstock
quelle

Antworten:

480

Klicken Sie hier, um weitere Informationen zu erhalten. Grundsätzlich sind jedoch keine Erweiterungsmethoden erforderlich. Es ist bereits eingebrannt, nur nicht sehr intuitiv.

Url.Action("Action", null, null, Request.Url.Scheme);
Adam Boddington
quelle
6
Interessant, wenn Sie also das Protokoll angeben, ist die URL absolut
Casebash
24
Diese Antwort ist die bessere. Auf diese Weise kann Resharper weiterhin überprüfen, ob die Aktion und der Controller vorhanden sind. Ich würde die Verwendung von Request.Url.Scheme anstelle von http vorschlagen. Auf diese Weise werden sowohl http als auch https unterstützt.
Pbirkoff
2
@Pbirkoff, stimmen Sie zu, dass dies die beste Antwort ist, aber Sie möchten vielleicht wissen, dass Sie Ihre eigenen Methoden für ReSharper mit Anmerkungen versehen können, um zu wissen, dass Parameter Aktionen / Controller darstellen. Auf diese Weise kann R # die von Ihnen angegebenen Zeichenfolgen weiterhin validieren, da dies so gut funktioniert.
Drew Noakes
3
Eine kleine Verbesserung könnte sein , zu ersetzen „http“ mit , Request.Url.Schemeso dass , wenn Sie HTTPS verwenden die URL generiert wird auch HTTPS verwenden.
Erik Schierboom
1
Dies funktioniert auch für Html.ActionLink(alle Methoden, die ein Protokoll verwenden, die letzten 2 in MVC 4 zum Beispiel)
Chris
74

Erweitern Sie den 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;
        }
    }
}

Dann nenne es so

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

BEARBEITEN - RESHARPER-ANMERKUNGEN

Der am besten bewertete Kommentar zu der akzeptierten Antwort lautet: This answer is the better one, this way Resharper can still validate that the Action and Controller exists.Hier ist ein Beispiel, wie Sie das gleiche Verhalten erzielen können.

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

Unterstützende Informationen:

Charlino
quelle
3
Ich würde auch optionale Parameter für diese Lösung hinzufügen. Dies sollte alle Fälle abdecken.
Eugeniu Torica
Sehr schön! Ich habe diesen Code verwendet, aber das einzige Argument relativeUrl angegeben, damit der Aufrufer ihn mit einer beliebigen URL-Methode (Router-Werte usw.) erstellen kann, und Ihre Methode kann nur dafür verantwortlich sein, ihn relativ zu machen. Meins ist also: AbsoluteUrl (diese UrlHelper-URL, Zeichenfolge relativeUrl).
Rob Kent
26
<%= Url.Action("About", "Home", null, Request.Url.Scheme) %>
<%= Url.RouteUrl("Default", new { Action = "About" }, Request.Url.Scheme) %>
Ryan Sampson
quelle
21

Ich habe die Antwort von @Charlino als Leitfaden verwendet.

Die ASP.NET MVC-Dokumentation für UrlHelper zeigt, dass Url.Action eine vollständig qualifizierte URL zurückgibt, wenn ein Hostname und ein Protokoll übergeben werden. Ich habe diese Hilfsprogramme erstellt , um die Bereitstellung des Hostnamens und des Protokolls zu erzwingen. Die mehrfachen Überladungen spiegeln die Überladungen für Url.Action wider:

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

    }
}
Raleigh Buckner
quelle
4
Danke für den Code, hat mir sehr geholfen, aber es gibt ein Problem mit dieser Lösung, das normalerweise während der Entwicklung auftritt. Wenn die Site an einem bestimmten Port gehostet wird, sind die Portinformationen in requestUrl.Authority enthalten , z. B. localhost: 4423 . Aus irgendeinem Grund hängt die Action-Methode den Port erneut an. Entweder ist dies ein Fehler in der Aktionsmethode, oder Sie sollten den Port hier nicht angeben. Aber welche der verfügbaren Eigenschaften in der Anfrage ist die richtige (DnsSafeHost oder Host)? Nun, die Lösung ist ziemlich einfach: Geben Sie einfach null an und die Action-Methode füllt den richtigen Wert aus.
Ntziolis
Ich habe die Antwort aktualisiert, um den Vorschlag von @ ntziolis aufzunehmen.
Andrew Arnott
3

Ich bin nicht sicher, ob es eine eingebaute Methode gibt, aber Sie könnten Ihre eigene HtmlHelper-Methode rollen.

So etwas wie das Folgende

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

Dann nenne es so

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

HTHs, Charles

Charlino
quelle
2

Vollständige Antwort mit Argumenten wäre:

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

und das wird eine absolute URL erzeugen

Dashrath
quelle
1

Gleiches Ergebnis, aber etwas sauberer (keine Verkettung / Formatierung von Zeichenfolgen):

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;
}
vegetarisch
quelle
0

Vielleicht das (?):

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

env: dotnet core version 1.0.4

Url.Action("Join",null, null,Context.Request.IsHttps?"https":"http");
Guhyeon
quelle