Cómo obtener la URL de la página actual en MVC 3


Estoy usando el plugin de comentarios de Facebook en un blog que estoy construyendo. Tiene algunas etiquetas FBXML que son interpretadas por el javascript de facebook al que se hace referencia en la página.

Todo esto funciona bien, pero tengo que pasar la URL actual y completa al plugin.

<div style="width: 900px; margin: auto;">
    <div id="fb-root"></div>
    <fb:comments href="URL HERE" num_posts="10" width="900"></fb:comments>
</div>

¿Cuál es la mejor manera de obtener la URL de la página actual? La URL de la solicitud.

Solución

Aquí está el código final de mi solución:

<fb:comments href="@Request.Url.AbsoluteUri" num_posts="15" width="900"></fb:comments>
Author: Shaun Wilson, 2011-03-15

8 answers

Podría utilizar el Request.RawUrl, Request.Url.OriginalString, Request.Url.ToString() o Request.Url.AbsoluteUri.

 471
Author: Darin Dimitrov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-11 22:42:59

Agregue este método de extensión a su código:

public static Uri UrlOriginal(this HttpRequestBase request)
{
  string hostHeader = request.Headers["host"];

  return new Uri(string.Format("{0}://{1}{2}",
     request.Url.Scheme, 
     hostHeader, 
     request.RawUrl));
}

Y luego puedes ejecutarlo desde la propiedad RequestContext.HttpContext.Request.

Hay un error (puede ser lateral, ver a continuación) en Asp.Net esto surge en máquinas que utilizan puertos distintos del puerto 80 para el sitio web local (un gran problema si los sitios web internos se publican a través de equilibrio de carga en IP virtual y los puertos se utilizan internamente para las reglas de publicación) por lo que Asp.Net siempre añadirá el puerto en la propiedad AbsoluteUri - incluso si la solicitud original no lo usa.

Este código asegura que la url devuelta siempre es igual a la Url que el navegador originalmente solicitó (incluido el puerto, ya que se incluiría en el encabezado del host) antes de que tenga lugar cualquier balanceo de carga, etc.

Al menos, lo hace en nuestro (bastante enrevesado!) medio ambiente :)

Si hay algún proxy funky en el medio que reescriba el encabezado del host, entonces esto tampoco funcionará.

Actualización 30 de Julio 2013

Como lo menciona @ KevinJones en los comentarios a continuación, la configuración que menciono en la siguiente sección ha sido documentada aquí: http://msdn.microsoft.com/en-us/library/hh975440.aspx

Aunque tengo que decir que no pude conseguir que funcione cuando lo intenté, pero eso podría ser solo yo haciendo un error tipográfico o algo así.

Actualización 9 de julio de 2012

Me encontré con esto hace un rato, y tenía la intención de actualizar esta respuesta, pero nunca lo hice. Cuando un voto positivo acabo de llegar con esta respuesta pensé que debería hacerlo ahora.

El' bug ' que menciono en Asp.Net se puede controlar con un valor AppSettings aparentemente indocumentado-llamado 'aspnet:UseHostHeaderForRequest' - es decir:

<appSettings>
  <add key="aspnet:UseHostHeaderForRequest" value="true" />
</appSettings>

Me encontré con esto mientras miraba HttpRequest.Url en ILSpy, indicado por ---> a la izquierda de la siguiente copia / pega de esa vista de ILSpy:

public Uri Url
{
  get
  {
    if (this._url == null && this._wr != null)
    {
      string text = this.QueryStringText;
      if (!string.IsNullOrEmpty(text))
      {
        text = "?" + HttpEncoder.CollapsePercentUFromStringInternal(text, 
          this.QueryStringEncoding);
      }
 ---> if (AppSettings.UseHostHeaderForRequestUrl)
      {
        string knownRequestHeader = this._wr.GetKnownRequestHeader(28);
        try
        {
          if (!string.IsNullOrEmpty(knownRequestHeader))
          {
            this._url = new Uri(string.Concat(new string[]
            {
              this._wr.GetProtocol(),
              "://",
              knownRequestHeader,
              this.Path,
              text 
            }));
          }
        }
        catch (UriFormatException)
        { }
     }
     if (this._url == null) { /* build from server name and port */
       ...

Personalmente no lo he usado-es indocumentado y por lo tanto no garantiza que se quede - sin embargo, podría hacer lo mismo lo que mencioné anteriormente. Para aumentar la relevancia en los resultados de búsqueda - y para reconocer a alguien más que parece haber descubierto esto - el ajuste 'aspnet:UseHostHeaderForRequest' también ha sido mencionado por Nick Aceves en Twitter

 47
Author: Andras Zoltan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-30 00:04:21
public static string GetCurrentWebsiteRoot()
{
    return HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority);
}
 12
Author: Brian Ogden,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-16 08:59:39
Request.Url.PathAndQuery

Debería funcionar perfectamente, especialmente si solo desea el Uri relativo (pero manteniendo los anillos de consulta)

 9
Author: Lucius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-26 22:04:40

Yo también estaba buscando esto por razones de Facebook y ninguna de las respuestas dadas hasta ahora funcionó como era necesario o son demasiado complicadas.

@Request.Url.GetLeftPart(UriPartial.Path)

Obtiene el protocolo completo, el host y la ruta "sin" la cadena de consultas. También incluye el puerto si está utilizando algo que no sea el 80 predeterminado.

 8
Author: johnw182,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-07 03:36:42

Mi favorito...

Url.Content(Request.Url.PathAndQuery)

O simplemente...

Url.Action()
 3
Author: Carter Medlin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-08 22:01:17

Una cosa que no se menciona en otras respuestas es la sensibilidad de mayúsculas y minúsculas, si va a ser referenciada en varios lugares (que no está en la pregunta original, pero vale la pena tomar en consideración ya que esta pregunta aparece en muchas búsquedas similares). Basado en otras respuestas, encontré que lo siguiente funcionó para mí inicialmente:

Request.Url.AbsoluteUri.ToString()

Pero con el fin de ser más confiable, esto se convirtió en:

Request.Url.AbsoluteUri.ToString().ToLower()

Y luego para mis requisitos (comprobar qué nombre de dominio el sitio está siendo accedido desde y mostrando el contenido relevante):

Request.Url.AbsoluteUri.ToString().ToLower().Contains("xxxx")

 0
Author: Lyall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-25 10:04:56

Para mí, el problema fue cuando intenté acceder a HTTPContext en el constructor del Controlador mientras que HTTPContext aún no está listo. Cuando se movió dentro del método Índice funcionó:

var uri = new Uri(Request.Url.AbsoluteUri);
url = uri.Scheme + "://" + uri.Host + "/";enter code here
 0
Author: numbtongue,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-13 12:19:31