Qual é o melhor método no ASP.NET para obter o domínio atual?

102

Estou me perguntando qual é a melhor maneira de obter o domínio atual no ASP.NET?

Por exemplo:

http://www.domainname.com/subdir/ deve render http://www.domainname.com http://www.sub.domainname.com/subdir/ deve render http://sub.domainname.com

Como um guia, devo ser capaz de adicionar um url como "/Folder/Content/filename.html" (digamos como gerado por Url.RouteUrl () na ASP.NET MVC) diretamente no URL e deve funcionar.

Matt Mitchell
fonte
3
Observe que o "domínio atual" aqui é na verdade o que o user-agent consumidor usou para chegar ao seu site, que em muitos casos é diferente do "URL oficial" do seu site, bem como do que o usuário final pode ter inserido no navegador ( proxy reverso, proxy de encaminhamento, nome de host interno, endereço IP, ...).
bzlm
1
Então, há uma maneira de obter o "URL oficial" (aquele do IIS?)
Matt Mitchell

Respostas:

186

Mesma resposta que MattMitchell, mas com algumas modificações. Em vez disso, verifica a porta padrão.

Editar: sintaxe atualizada e usando Request.Url.Authorityconforme sugerido

$"{Request.Url.Scheme}{System.Uri.SchemeDelimiter}{Request.Url.Authority}"
Carlos Muñoz
fonte
3
Existe um campo definido em .NET que posso usar em vez de ":"? Algo como System.Uri.PortDelimiter? Você sabe, apenas para consistência. :)
Jan Aagaard,
2
Não que eu saiba, Jan Aagaard, mas você sempre pode fazer um localmente. Eu faço isso para a maioria das strings e números "mágicos". Nesse caso, você usaria string.Empty em vez de "" na resposta de Carlos;)
vbullinger
8
Você pode usar Request.Url.Authoritycomo Korayem sugeriu em vez de Request.Url.Hoste Request.Url.Port.
Schmalls de
4
Em vez de concatenar strings, você deve usar a classe System.UriBuilder.
BrainSlugs83
3
@MattMitchell, parece não ter fundado os problemas com a Autoridade, é o equivalente a Host + ":" + Port, veja o código-fonte dotnetframework.org/default.aspx/DotNET/DotNET/8@0/untmp/…
Giuseppe
40

De acordo com este link, um bom ponto de partida é:

Request.Url.Scheme + System.Uri.SchemeDelimiter + Request.Url.Host 

No entanto, se o domínio for http://www.domainname.com:500, ocorrerá uma falha.

Algo como o seguinte é tentador para resolver isso:

int defaultPort = Request.IsSecureConnection ? 443 : 80;
Request.Url.Scheme + System.Uri.SchemeDelimiter + Request.Url.Host 
  + (Request.Url.Port != defaultPort ? ":" + Request.Url.Port : "");

No entanto, as portas 80 e 443 dependerão da configuração.

Como tal, você deve usar IsDefaultPortcomo na Resposta Aceita acima de Carlos Muñoz.

Matt Mitchell
fonte
1
Por que assumir a porta 80 aqui? Se você remover essa suposição, o código parecerá abrangente. Ao assumir a porta 80, você falhará em muitos cenários (consulte os comentários nas outras respostas). Se desejar remover o número da porta, se possível, você deve verificar se o número da porta é o padrão para o esquema em questão e se o esquema suporta números de porta padrão.
bzlm
Sim, veja a nota que a porta 80 pode ser uma má ideia. Não conheço nenhuma outra maneira de contornar isso, por isso mencionei que ele precisará ser dependente da configuração.
Matt Mitchell
1
Não sei se isso vai ajudar ou não, mas você também pode tentar: if Request.IsSecureConnection para determinar se HTTPS é usado ou não?
Erick Brown
1
@EricBrown - Sim, essa resposta não é muito boa em uma retrospectiva 5 anos depois. Eu iria com a resposta aceita de Carlos Muñoz para evitar esse problema.
Matt Mitchell
29
Request.Url.GetLeftPart(UriPartial.Authority)

Este é o esquema incluído.

Izlence
fonte
23
Eu adoraria estar na reunião quando eles vieram com esse nome
Simon_Weaver
20

AVISO! Para quem usa Current.Request .Url.Host. Entenda que você está trabalhando com base no PEDIDO ATUAL e que o pedido atual NÃO será SEMPRE com o seu servidor e às vezes pode ser com outros servidores.

Portanto, se você usar isso em algo como Application_BeginRequest () em Global.asax, em 99,9% do tempo estará tudo bem, mas 0,1% poderá obter algo diferente do nome de host do seu próprio servidor.

Um bom exemplo disso é algo que descobri há não muito tempo. Meu servidor tende a acessar http://proxyjudge1.proxyfire.net/fastenv de vez em quando. Application_BeginRequest () lida com essa solicitação com prazer, então se você chamar Request.Url.Host quando estiver fazendo essa solicitação, você receberá de volta proxyjudge1.proxyfire.net. Alguns de vocês podem estar pensando "não duh", mas vale a pena notar porque era um bug muito difícil de notar, já que acontecia apenas 0,1% das vezes: P

Este bug me forçou a inserir meu host de domínio como uma string nos arquivos de configuração.

Thirlan
fonte
Fez exatamente o mesmo. Meu domínio está em web.config agora.
Korayem
Mas acho que entendo - por que o seu servidor atingiu o proxyfire? Esse é o seu site? Mas, no geral, faz sentido - usar um objeto específico de solicitação durante um evento específico do aplicativo pode não funcionar muito bem. Existe perigo em um evento específico da solicitação, como um evento de ciclo de vida da página (Page.LoadCompleted, etc.)?
mlhDev
Não investiguei muito por que estava resolvendo o proxyfire. Certamente não era meu site, mas me indicou que Current.Request.Url não era 100% confiável. Depois de muita pesquisa, também descobri que determinar dinamicamente o nome do host não é fácil, devido a várias placas NIC, IPs e nomes de domínio que resolvem para o mesmo IP. Quanto à sua outra pergunta, Matt, não tenho certeza do que você quer dizer: (
Thirlan
então isso só ocorreu em Application_BeginRequest? Não vejo como o IIS poderia ter enviado essa solicitação ao seu aplicativo, a menos que você não tenha um cabeçalho de host definido, talvez.
Simon_Weaver
@Thirlan - Estou tentando depurar um problema que parece semelhante a este. Estou tentando obter o subdomínio usando Request.Url.Host e 'geralmente' funciona bem, mas nem sempre. Existe realmente alguma maneira em torno disso? Como algo mais na solicitação que pode estar correto?
scojomodena
14

Por que não usar

Request.Url.Authority

Ele retorna todo o domínio E a porta.

Você ainda precisa descobrir http ou https

Korayem
fonte
2
Isso também funciona. Para "descobrir" http ou https, simplesmente coloque "//" antes dele. Por exemplo, seria lido como href = "// @ Request.Url.Authority ..."
EdwardM
2

Caminho simples e curto (suporta esquema, domínio e porta):

Usar Request.GetFullDomain()

// Add this class to your project
public static class HttpRequestExtensions{
    public static string GetFullDomain(this HttpRequestBase request)
    {
        var uri= request?.UrlReferrer;
        if (uri== null)
            return string.Empty;
        return uri.Scheme + Uri.SchemeDelimiter + uri.Authority;
    }
}

// Now Use it like this:
Request.GetFullDomain();
// Example output:    https://www.example.com:5031
// Example output:    http://www.example.com:5031
// Example output:    https://www.example.com
RAM
fonte
1

Outra maneira:


string domain;
Uri url = HttpContext.Current.Request.Url;
domain= url.AbsoluteUri.Replace(url.PathAndQuery, string.Empty);

fonte
Resposta simples, mas simplesmente incrível!
Shiroy
1

E se:

NameValueCollection vars = HttpContext.Current.Request.ServerVariables;
string protocol = vars["SERVER_PORT_SECURE"] == "1" ? "https://" : "http://";
string domain = vars["SERVER_NAME"];
string port = vars["SERVER_PORT"];
Derek Lawless
fonte
0

Usando UriBuilder:

    var relativePath = ""; // or whatever-path-you-want
    var uriBuilder = new UriBuilder
    {
        Host = Request.Url.Host,
        Path = relativePath,
        Scheme = Request.Url.Scheme
    };

    if (!Request.Url.IsDefaultPort)
        uriBuilder.Port = Request.Url.Port;

    var fullPathToUse = uriBuilder.ToString();
Darren
fonte
-1

E se:

String domain = "http://" + Request.Url.Host
Jwalkerjr
fonte
Nada mal, mas e se o seu site tiver páginas seguras, por exemplo, https: // E se o seu domínio não estiver hospedado na porta 80?
Matt Mitchell de