2009-01-12 16 views
207

Ich brauche so etwas wie dies zu tun:Wie finde ich die absolute URL einer Aktion in ASP.NET MVC?

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

ich die Beta-Version von MVC, aber ich kann nicht herausfinden, wie die absolute URL einer Aktion zu bekommen. Ich möchte etwas in der Art machen:

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

Gibt es dafür eine Hilfs- oder Page-Methode?

Antwort

427

Klicken Sie here für weitere Informationen, aber esentially gibt es keine Notwendigkeit für Erweiterungsmethoden. Es ist bereits gebacken, nur nicht auf eine sehr intuitive Art und Weise.

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

Interessant, also, wenn Sie das Protokoll angeben, ist die URL absolut – Casebash

+21

Diese Antwort ist die bessere, auf diese Weise kann Resharper noch validieren, dass die Aktion und Controller vorhanden ist. Ich würde die Verwendung von Request.Url.Scheme anstelle von http vorschlagen, auf diese Weise http und https werden beide 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 bereitgestellten Strings immer noch validieren, da dies sehr gut funktioniert. –

3

Ich bin mir nicht sicher, ob es eine eingebaute Möglichkeit dafür gibt, aber Sie könnten Ihre eigene HtmlHelper-Methode erstellen.

So etwas wie die folgenden

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 nennen es ähnliche

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

HTHS, Charles

66

Erweitere 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 nennen wie diese

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

EDIT - ReSharper ANNOTATIONS

Die upvoted Kommentar über die akzeptierte Antwort ist This answer is the better one, this way Resharper can still validate that the Action and Controller exists. So, hier ist ein Beispiel, wie Sie das gleiche Verhalten zu bekommen.

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

Supporting Info:

+3

ich auch optionale Parameter für diese Lösung hinzufügen würde. Dies sollte alle Fälle abdecken. –

+0

Sehr schön! Ich habe diesen Code verwendet, aber ich habe das einzige Argument relativUrl gemacht, so dass der Aufrufer es mit einer beliebigen Url-Methode erstellen kann (Router-Werte usw.), und Ihre Methode kann nur dafür verantwortlich sein, es relativ zu machen. Also meins ist: AbsoluteUrl (diese UrlHelper URL, String relativeUrl). –

+2

Ich bevorzuge diese Antwort, weil es meinen Code lesbarer macht. –

1

gleiches Ergebnis, aber ein wenig saubere (keine String-Verkettung/Formatierung):

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

Mit @Charlino ‚s Antwort als Leitfaden, ich kam auf diese Idee.

Die ASP.NET MVC documentation for UrlHelper zeigt, dass Url.Action eine voll qualifizierte URL zurückgibt, wenn ein Hostname und ein Protokoll übergeben werden. Ich erstellte diese Helfer, um den Hostnamen und das Protokoll zu erzwingen. Die mehrfachen Überlastungen spiegeln die Überlastung für Url.Action:

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 für den Code, hat mir sehr geholfen, aber es gibt ein Problem mit dieser Lösung, die normalerweise während der Entwicklung auftritt. Wenn die Site auf einem bestimmten Port gehostet wird, ist die Port-Information in * requestUrl.Authority * enthalten, wie * localhost: 4423 *. Aus irgendeinem Grund hängt die Aktionsmethode den Port erneut an. Entweder ist dies ein Fehler innerhalb der Aktionsmethode oder Sie sollten den Port hier nicht bereitstellen. Aber welche der verfügbaren Eigenschaften auf der Anfrage ist die richtige (DnsSafeHost oder Host)? Nun, die Lösung ist ziemlich einfach: Just supply * null * und die Action-Methode wird den richtigen Wert ausfüllen. – ntziolis

+0

Ooh, beste Antwort hier – eouw0o83hf

+0

Ich habe die Antwort aktualisiert, um @ ntziolis Vorschlag einzubeziehen. –

0

Vielleicht (?):

<%= 
    Request.Url.GetLeftPart(UriPartial.Authority) + 
    Url.Action("Action1", "Controller2", new {param1="bla", param2="blabla" }) 
%> 
24
<%= Url.Action("About", "Home", null, Request.Url.Scheme) %> 
<%= Url.RouteUrl("Default", new { Action = "About" }, Request.Url.Scheme) %> 
+0

Das hat sehr gut für mich funktioniert - danke –

0

env: Dotnet Core-Version 1.0.4

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

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 produziert

Verwandte Themen