Jak znaleźć bezwzględny adres URL akcji w ASP.NET MVC?


239

Muszę zrobić coś takiego:

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

Korzystam z wersji beta MVC, ale nie mogę dowiedzieć się, jak uzyskać bezwzględny adres URL akcji. Chciałbym zrobić coś takiego:

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

Czy istnieje do tego pomocnik lub metoda strony?

Odpowiedzi:


480

Kliknij tutaj, aby uzyskać więcej informacji, ale zasadniczo nie ma potrzeby stosowania metod rozszerzenia. Jest już upieczony, ale nie w bardzo intuicyjny sposób.

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

6
Ciekawe, więc jeśli podasz protokół, adres URL jest absolutny
Casebash

24
Ta odpowiedź jest lepsza, w ten sposób Resharper nadal może sprawdzić, czy działanie i kontroler istnieją. Sugerowałbym użycie Request.Url.Scheme zamiast http, w ten sposób obsługiwane są zarówno http, jak i https.
Pbirkoff

2
@Pbirkoff, zgadzam się, że jest to najlepsza odpowiedź, ale możesz chcieć wiedzieć, że możesz opatrzyć adnotacjami własne metody, aby ReSharper wiedział, że parametry reprezentują działania / kontrolery. W ten sposób R # może nadal sprawdzać ciągi, które podajesz, ponieważ robi to dobrze.
Drew Noakes,

3
Niewielka poprawa może być zastąpienie „http” z Request.Url.Schemetak, że jeśli używasz HTTPS url generowany będzie również korzystać z protokołu HTTPS.
Erik Schierboom,

1
Działa to Html.ActionLinkrównież dla (jednej z metod wykorzystujących protokół, na przykład ostatnich 2 w MVC 4)
Chris

74

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

Nazwij to tak

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

EDYCJA - REZERWACJE NIŻSZE

Najbardziej pozytywny komentarz do zaakceptowanej odpowiedzi brzmi: This answer is the better one, this way Resharper can still validate that the Action and Controller exists.Oto przykład, w jaki sposób można uzyskać takie samo zachowanie.

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

Informacje dodatkowe:


3
Dodałbym również opcjonalne parametry dla tego rozwiązania. Powinno to obejmować wszystkie przypadki.
Eugeniu Torica

Bardzo dobrze! Użyłem tego kodu, ale podałem jedyny argument relativeUrl, aby wywołujący mógł go utworzyć przy użyciu dowolnej metody Url, którą lubią (wartości routera itp.), A twoja metoda może być po prostu odpowiedzialna za uczynienie go względnym. Więc moje to: AbsoluteUrl (ten adres URL UrlHelper, string relativeUrl).
Rob Kent

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

21

Używając odpowiedzi @Charlino jako przewodnika, wymyśliłem to.

Dokumentacja ASP.NET MVC dla UrlHelper pokazuje, że Url.Action zwróci w pełni kwalifikowany adres URL, jeśli nazwa hosta i protokół zostaną przekazane. Utworzyłem te pomocniki, aby wymusić podanie nazwy hosta i protokołu. Wielokrotne przeciążenia odzwierciedlają przeciążenia 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
Dziękuję za kod, bardzo mi pomogło, ale jest problem z tym rozwiązaniem, które zwykle pojawia się podczas programowania. Jeśli witryna jest hostowana na określonym porcie, informacje o porcie są zawarte w requestUrl.Authority , np. Localhost : 4423 . Z jakiegoś powodu metoda Action ponownie dołącza port. Więc albo jest to błąd w metodzie akcji, albo nie należy tutaj podawać portu. Ale która z dostępnych właściwości na żądanie jest właściwa (DnsSafeHost lub Host)? Cóż, rozwiązanie jest dość proste: wystarczy podać wartość null, a metoda Action wypełni właściwą wartość.
ntziolis

Zaktualizowałem odpowiedź, aby uwzględnić sugestię @ ntziolis.
Andrew Arnott,

3

Nie jestem pewien, czy istnieje wbudowany sposób, aby to zrobić, ale możesz rzucić własną metodę HtmlHelper.

Coś takiego jak poniżej

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

Nazwij to tak

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

HTH, Charles


2

Pełna odpowiedź z argumentami brzmiałaby:

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

i to da absolutny adres URL


1

Ten sam wynik, ale trochę czystszy (bez łączenia / formatowania ciągów):

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

Może to (?):

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

0

env: wersja jądra dotnet 1.0.4

Url.Action("Join",null, null,Context.Request.IsHttps?"https":"http");
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.