Qual è il metodo migliore in ASP.NET per ottenere il dominio corrente?


102

Mi chiedo quale sia il modo migliore per ottenere il dominio corrente in ASP.NET?

Per esempio:

http://www.domainname.com/subdir/ dovrebbe restituire http://www.domainname.com http://www.sub.domainname.com/subdir/ dovrebbe restituire http://sub.domainname.com

Come guida, dovrei essere in grado di aggiungere un URL come "/Folder/Content/filename.html" (diciamo come generato da Url.RouteUrl () in ASP.NET MVC) direttamente sull'URL e dovrebbe funzionare.


3
Tieni presente che il "dominio corrente" qui è in realtà ciò che lo user-agent utilizzato per accedere al tuo sito, che in molti casi è diverso dall '"URL ufficiale" del tuo sito e da quello che l'utente finale potrebbe aver inserito nel proprio browser ( proxy inverso, proxy di inoltro, nome host interno, indirizzo IP, ...).
bzlm

1
Quindi c'è un modo per ottenere l '"URL ufficiale" (quello da IIS?)
Matt Mitchell

Risposte:


186

Stessa risposta di MattMitchell ma con alcune modifiche. Questo controlla invece la porta predefinita.

Modifica: sintassi aggiornata e utilizzo Request.Url.Authoritycome suggerito

$"{Request.Url.Scheme}{System.Uri.SchemeDelimiter}{Request.Url.Authority}"

3
Esiste un campo definito in .NET, che posso usare al posto di ":"? Qualcosa come System.Uri.PortDelimiter? Sai, solo per coerenza. :)
Jan Aagaard

2
Non che io sappia, Jan Aagaard, ma potresti sempre crearne uno a livello locale. Lo faccio per la maggior parte delle stringhe e dei numeri "magici". Se è per questo, dovresti usare string.Empty invece di "" nella risposta di Carlos;)
vbullinger

8
Puoi usare Request.Url.Authoritycome suggerito da Korayem al posto di Request.Url.Hoste Request.Url.Port.
Schmalls

4
Invece di concatenare le stringhe, dovresti usare la classe System.UriBuilder.
BrainSlugs83

3
@MattMitchell, sembra non fondare i problemi con Authority, è l'equivalente di Host + ":" + Port, vedi codice sorgente dotnetframework.org/default.aspx/DotNET/DotNET/8@0/untmp/…
Giuseppe Romagnuolo

40

Secondo questo link un buon punto di partenza è:

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

Tuttavia, se il dominio è http://www.domainname.com:500 , l'operazione fallirà.

Qualcosa di simile al seguente è tentato di risolvere questo problema:

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

Tuttavia, le porte 80 e 443 dipenderanno dalla configurazione.

Come tale, dovresti usare IsDefaultPortcome nella risposta accettata sopra di Carlos Muñoz.


1
Perché assumere la porta 80 qui? Se rimuovi questa ipotesi, il codice appare come un generico. Quando si assume la porta 80, si fallirà in molti scenari (vedere i commenti su altre risposte). Se si desidera rimuovere il numero di porta, se possibile, è necessario verificare che il numero di porta sia quello predefinito per lo schema in questione e che lo schema supporti i numeri di porta predefiniti.
bzlm

Sì, vedi la nota che la porta 80 potrebbe essere una cattiva idea. Non conosco nessun altro modo per aggirare questo problema, motivo per cui ho detto che dovrà dipendere dalla configurazione.
Matt Mitchell

1
Non so se questo aiuterà o no ma potresti anche provare: if Request.IsSecureConnection per determinare se HTTPS viene utilizzato o no?
Erick Brown

1
@EricBrown - Sì, questa risposta non è eccezionale in retrospettiva 5 anni dopo. Andrei con la risposta accettata di Carlos Muñoz per evitare questo problema.
Matt Mitchell

29
Request.Url.GetLeftPart(UriPartial.Authority)

Questo è schema incluso.


23
Mi piacerebbe essere stato alla riunione quando hanno
inventato

20

AVVERTIMENTO! A chiunque utilizzi Current.Request .Url.Host. Comprendi che stai lavorando in base alla RICHIESTA CORRENTE e che la richiesta corrente non sarà SEMPRE con il tuo server e talvolta può essere con altri server.

Quindi, se lo usi in qualcosa come Application_BeginRequest () in Global.asax, il 99,9% delle volte andrà bene, ma lo 0,1% potresti ottenere qualcosa di diverso dal nome host del tuo server.

Un buon esempio di questo è qualcosa che ho scoperto non molto tempo fa. Il mio server tende a colpire http://proxyjudge1.proxyfire.net/fastenv di tanto in tanto. Application_BeginRequest () gestisce volentieri questa richiesta, quindi se chiami Request.Url.Host quando effettua questa richiesta riceverai indietro proxyjudge1.proxyfire.net. Alcuni di voi potrebbero pensare "no duh", ma vale la pena notare perché era un bug molto difficile da notare poiché si verificava solo lo 0,1% delle volte:

Questo bug mi ha costretto a inserire il mio host di dominio come stringa nei file di configurazione.


Ha fatto esattamente lo stesso. Il mio dominio è ora in web.config.
Korayem

Io penso che ho capito, anche se - Perché il vostro server di colpo Proxyfire? Quello è il tuo sito? Ma, nel complesso, ha senso: l'utilizzo di un oggetto specifico della richiesta durante un evento specifico dell'applicazione potrebbe non funzionare troppo bene. Esiste un pericolo in un evento specifico della richiesta, come un evento del ciclo di vita della pagina (Page.LoadCompleted, ecc.)?
mlhDev

Non ho indagato troppo sul motivo per cui si stava risolvendo con il proxyfire. Certamente non era il mio sito, ma mi indicava che Current.Request.Url non era affidabile al 100%. Dopo molte ricerche ho anche scoperto che determinare dinamicamente il tuo hostname non è facile, a causa di più schede NIC, IP e nomi di dominio che risolvono lo stesso IP. Per quanto riguarda l'altra tua domanda Matt, non sono sicuro di cosa intendi: (
Thirlan

quindi questo è avvenuto sempre e solo in Application_BeginRequest? Non vedo come IIS avrebbe potuto inviare questa richiesta alla tua app a meno che tu non abbia impostato un'intestazione host forse?
Simon_Weaver

@Thirlan - Sto cercando di eseguire il debug di un problema che suona simile a questo. Sto cercando di ottenere il sottodominio utilizzando Request.Url.Host e "di solito" funziona bene, ma non sempre. C'è davvero qualcosa intorno a questo? Come qualcos'altro nella richiesta che potrebbe essere corretto?
scojomodena

14

Perché non usare

Request.Url.Authority

Restituisce l'intero dominio E la porta.

Devi ancora calcolare http o https


2
Anche questo funziona. Per "visualizzare" http o https, è sufficiente inserire "//" prima di esso. Quindi, ad esempio, verrebbe letto come href = "// @ Request.Url.Authority ..."
EdwardM

2

Modo semplice e breve (supporta schema, dominio e porta):

Uso 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

1

Un altro modo:


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

Risposta semplice ma semplicemente fantastica!
Shiroy

1

Che ne dite di:

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"];

0

Utilizzando 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();

-1

Che ne dite di:

String domain = "http://" + Request.Url.Host

Non male, ma cosa succede se il tuo sito ha pagine protette, ad esempio https: // E se il tuo dominio non è ospitato sulla porta 80?
Matt Mitchell
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.