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.