c# route Como obter o URL da página atual no MVC 3




mvc get url address (7)

Eu estou usando o plugin de comentários do Facebook em um blog que estou construindo. Tem algumas tags FBXML que são interpretadas pelo javascript do facebook que é referenciado na página.

Isso tudo funciona bem, mas eu tenho que passar a URL atual e totalmente qualificada para o 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>

Qual é a melhor maneira de obter o URL da página atual? O URL da solicitação.

Solução

Aqui está o código final da minha solução:

<fb:comments href="@Request.Url.AbsoluteUri" num_posts="15" width="900"></fb:comments>

public static string GetCurrentWebsiteRoot()
{
    return HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority);
}

Eu também estava procurando por isso por razões do Facebook e nenhuma das respostas dadas até agora funcionou conforme necessário ou são muito complicadas.

@Request.Url.GetLeftPart(UriPartial.Path)

Obtém o protocolo completo, host e caminho "sem" a querystring. Também inclui a porta se você estiver usando algo diferente do padrão 80.


Uma coisa que não é mencionada em outras respostas é a diferenciação de maiúsculas e minúsculas, se ela será referenciada em vários lugares (o que não está na pergunta original, mas vale a pena levar em consideração, já que essa pergunta aparece em muitas buscas semelhantes. ). Baseado em outras respostas, achei que o seguinte funcionou para mim inicialmente:

Request.Url.AbsoluteUri.ToString()

Mas, para ser mais confiável, isso se tornou:

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

E, em seguida, para meus requisitos (verificando o nome de domínio do qual o site está sendo acessado e mostrando o conteúdo relevante):

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


Request.Url.PathAndQuery

deve funcionar perfeitamente, especialmente se você quer apenas o Uri relativo (mas mantendo querystrings)


Adicione este método de extensão ao seu 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));
}

E então você pode executá-lo fora da propriedade RequestContext.HttpContext.Request .

Há um bug (pode ser acompanhado de um passo a lado, veja abaixo) no Asp.Net que surge em máquinas que usam portas diferentes da porta 80 para o site local (um grande problema se sites internos são publicados via balanceamento de carga em IP virtual e portas são usadas internamente para regras de publicação) pelo qual o Asp.Net sempre adicionará a porta na propriedade AbsoluteUri - mesmo que a solicitação original não a use.

Esse código garante que o URL retornado seja sempre igual ao URL originalmente solicitado pelo navegador (incluindo a porta - como seria incluído no cabeçalho do host) antes que qualquer balanceamento de carga etc. ocorra.

Pelo menos, isso acontece em nosso ambiente (bastante complicado!) :)

Se houver algum proxy no meio que reescreva o cabeçalho do host, isso também não funcionará.

Atualização de 30 de julho de 2013

Como mencionado por @KevinJones nos comentários abaixo - a configuração mencionada na próxima seção foi documentada aqui: http://msdn.microsoft.com/en-us/library/hh975440.aspx

Embora eu tenha que dizer que não consegui fazê-lo funcionar quando tentei - mas isso poderia ser apenas eu fazendo um erro de digitação ou algo assim.

Atualização de 9 de julho de 2012

Eu me deparei com isso há pouco tempo, e pretendia atualizar essa resposta, mas nunca o fiz. Quando um upvote acabou de chegar a esta resposta, eu pensei que deveria fazê-lo agora.

O 'bug' que eu menciono no Asp.Net pode ser controlado com um valor appSettings aparentemente não documentado - chamado 'aspnet:UseHostHeaderForRequest' - por exemplo:

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

Eu me deparei com isso enquanto olhava para o HttpRequest.Url no ILSpy - indicado pelo ---> à esquerda da seguinte cópia / colagem daquela visão do 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 */
       ...

Eu pessoalmente não o usei - é indocumentado e, portanto, não tenho garantia de ficar por perto - no entanto, ele pode fazer a mesma coisa que eu mencionei acima. Para aumentar a relevância nos resultados de pesquisa - e para reconhecer alguém que parece ter descoberto isso - a 'aspnet:UseHostHeaderForRequest' também foi mencionada por Nick Aceves no Twitter



Para mim, o problema foi quando tentei acessar o HTTPContext no construtor do Controller enquanto o HTTPContext ainda não está pronto. Quando movido dentro do método Index, funcionou:

var uri = new Uri(Request.Url.AbsoluteUri);
url = uri.Scheme + "://" + uri.Host + "/";enter code here




razor