2009-01-12 10 views
207

tengo que hacer algo como esto:¿Cómo puedo encontrar la URL absoluta de una acción en ASP.NET MVC?

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

estoy usando la versión beta de MVC, pero no puedo encontrar la manera de obtener la URL absoluta de una acción. Me gustaría hacer algo como esto:

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

¿Hay un ayudante o método de página para esto?

Respuesta

427

Haga clic here para obtener más información, pero absoluto se refiere a que no hay necesidad de métodos de extensión. Ya está preparado, solo que no de una manera muy intuitiva.

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

Interesante, así que si especifica el protocolo, la URL es absoluta – Casebash

+21

Esta respuesta es la mejor, de esta manera Resharper aún puede validar que existe la Acción y el Controlador. Yo sugeriría el uso de Request.Url.Scheme en lugar de http, de esa manera tanto http como https son compatibles. – Pbirkoff

+2

@Pbirkoff, acepta que esta es la mejor respuesta, pero le gustaría saber que puede anotar sus propios métodos para que ReSharper sepa que los parámetros representan acciones/controladores. De esa forma, R # aún puede validar las cadenas que usted proporciona, ya que lo hace muy bien. –

3

No estoy seguro de si hay una forma integrada para hacerlo, pero podría ejecutar su propio método HtmlHelper.

algo como lo siguiente

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

Entonces llaman como éste

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

HTHS, Charles

66

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

A continuación, llamarlo como esto

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

EDITAR - ANOTACIONES ReSharper

El comentario más upvoted en la respuesta aceptada es This answer is the better one, this way Resharper can still validate that the Action and Controller exists. Así que aquí es un ejemplo de cómo se puede conseguir el mismo comportamiento.

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

Apoyo Info:

+3

yo añadiría también parámetros opcionales para esta solución. Esto debería cubrir todos los casos. –

+0

¡Muy bonito! Usé este código pero hice el único argumento relativeUrl para que la persona que llama pueda crearlo usando el método de Url que prefiera (valores de enrutador, etc.), y su método puede ser responsable de hacerlo relativo. Así que el mío es: AbsoluteUrl (esta UrlHelper url, string relativeUrl). –

+2

Prefiero esta respuesta, porque hace que mi código sea más legible. –

1

mismo resultado, pero un poco más limpio (sin concatenación de cadenas/formato):

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

Usando @Charlino 's respuesta como una guía, se me ocurrió esto.

El ASP.NET MVC documentation for UrlHelper muestra que Url.Action devolverá un Url totalmente calificado si se pasan un nombre de host y protocolo. Creé estos helpers para forzar que se proporcionen el nombre de host y el protocolo. Las múltiples sobrecargas reflejan las sobrecargas de 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 para el código, me ayudó mucho, pero hay un problema con esta solución que generalmente aparece durante el desarrollo. Si el sitio está alojado en un puerto específico, la información del puerto se incluye en * requestUrl.Authority *, como * localhost: 4423 *. Por algún motivo, el método de Acción vuelve a agregar el puerto. Entonces, este es un error dentro del Método de Acción o se supone que no debes proporcionar el puerto aquí. Pero, ¿cuál de las Propiedades disponibles en la solicitud es la correcta (DnsSafeHost o Host)? Bueno, la solución es bastante simple: simplemente suministre * null * y el método de acción completará el valor correcto. – ntziolis

+0

Ooh, la mejor respuesta aquí – eouw0o83hf

+0

He actualizado la respuesta para incorporar la sugerencia de @ntziolis. –

0

Tal vez esto (?):

<%= 
    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

Esto funcionó muy bien para mí, gracias –

0

env: dotnet núcleo versión 1.0.4

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

La respuesta completa con argumentos sería:

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

y que producirá una URL absoluta

Cuestiones relacionadas