Was ist die beste Methode in ASP.NET, um die aktuelle Domäne abzurufen?

102

Ich frage mich, wie Sie die aktuelle Domain am besten in ASP.NET erhalten können.

Zum Beispiel:

http://www.domainname.com/subdir/ sollte Ausbeute http://www.domainname.com http://www.sub.domainname.com/subdir/ sollte Ausbeute http://sub.domainname.com

Als Leitfaden sollte ich in der Lage sein, eine URL wie "/Folder/Content/filename.html" (etwa wie von Url.RouteUrl () in ASP.NET MVC generiert) direkt zur URL hinzuzufügen, und es sollte funktionieren.

Matt Mitchell
quelle
3
Beachten Sie, dass die "aktuelle Domain" hier tatsächlich das ist, was der konsumierende Benutzeragent verwendet hat, um zu Ihrer Site zu gelangen. Dies unterscheidet sich in vielen Fällen von der "offiziellen URL" Ihrer Site sowie von dem, was der Endbenutzer möglicherweise in seinen Browser eingegeben hat ( Reverse Proxy, Forward Proxy, interner Hostname, IP-Adresse, ...).
bzlm
1
Gibt es also eine Möglichkeit, die "offizielle URL" (die von IIS?) Zu erhalten
Matt Mitchell

Antworten:

186

Gleiche Antwort wie bei MattMitchell, jedoch mit einigen Änderungen. Dadurch wird stattdessen nach dem Standardport gesucht.

Bearbeiten: Aktualisierte Syntax und Verwendung Request.Url.Authoritywie vorgeschlagen

$"{Request.Url.Scheme}{System.Uri.SchemeDelimiter}{Request.Url.Authority}"
Carlos Muñoz
quelle
3
Gibt es ein in i .NET definiertes Feld, das ich anstelle von ":" verwenden kann? So etwas wie System.Uri.PortDelimiter? Sie wissen, nur aus Gründen der Konsistenz. :)
Jan Aagaard
2
Nicht das ich wüsste, Jan Aagaard, aber man könnte immer einen vor Ort machen. Ich mache das für die meisten "magischen" Zeichenfolgen und Zahlen. Für diese Angelegenheit würden Sie dann string.Empty anstelle von "" in Carlos 'Antwort verwenden;)
vbullinger
8
Sie können Request.Url.Authoritywie von Korayem vorgeschlagen anstelle von Request.Url.Hostund verwenden Request.Url.Port.
Schmalls
4
Anstatt Zeichenfolgen zu verketten, sollten Sie die System.UriBuilder-Klasse verwenden.
BrainSlugs83
3
@MattMitchell, es scheint nicht die Probleme mit Authority begründet, es ist das Äquivalent von Host + ":" + Port, siehe Quellcode dotnetframework.org/default.aspx/DotNET/DotNET/8@0/untmp/…
Giuseppe Romagnuolo
40

Gemäß diesem Link ist ein guter Ausgangspunkt:

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

Wenn die Domain jedoch http://www.domainname.com:500 lautet, schlägt dies fehl.

So etwas wie das Folgende ist verlockend, um dieses Problem zu lösen:

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

Die Ports 80 und 443 hängen jedoch von der Konfiguration ab.

Als solches sollten Sie IsDefaultPortwie in der oben genannten akzeptierten Antwort von Carlos Muñoz verwenden.

Matt Mitchell
quelle
1
Warum hier Port 80 annehmen? Wenn Sie diese Annahme entfernen, sieht der Code wie ein Allheilmittel aus. Wenn Sie von Port 80 ausgehen, schlagen Sie in vielen Szenarien fehl (siehe Kommentare zu anderen Antworten). Wenn Sie die Portnummer nach Möglichkeit entfernen möchten, müssen Sie überprüfen, ob die Portnummer die Standardportnummer für das betreffende Schema ist und ob das Schema Standardportnummern unterstützt.
bzlm
Ja, siehe Hinweis, dass Port 80 eine schlechte Idee sein kann. Ich kenne keinen anderen Weg, weshalb ich erwähnt habe, dass es konfigurationsabhängig sein muss.
Matt Mitchell
1
Ich weiß nicht, ob dies helfen wird oder nicht, aber Sie könnten auch versuchen: ob Request.IsSecureConnection, um festzustellen, ob HTTPS verwendet wird oder nicht?
Erick Brown
1
@EricBrown - Ja, diese Antwort ist in Retropsect 5 Jahre später nicht großartig. Ich würde mich der akzeptierten Antwort von Carlos Muñoz anschließen, um dieses Problem zu vermeiden.
Matt Mitchell
29
Request.Url.GetLeftPart(UriPartial.Authority)

Dies ist Schema enthalten.

izlence
quelle
23
Ich wäre gerne in der Besprechung gewesen, als sie diesen Namen
erfanden
20

WARNUNG! An alle, die Current.Request .Url.Host verwenden. Verstehen Sie, dass Sie basierend auf der AKTUELLEN ANFRAGE arbeiten und dass die aktuelle Anforderung nicht IMMER bei Ihrem Server und manchmal auch bei anderen Servern sein wird.

Wenn Sie dies also in etwas wie Application_BeginRequest () in Global.asax verwenden, ist es in 99,9% der Fälle in Ordnung, aber in 0,1% erhalten Sie möglicherweise etwas anderes als den Hostnamen Ihres eigenen Servers.

Ein gutes Beispiel dafür habe ich vor kurzem entdeckt. Mein Server neigt von Zeit zu Zeit dazu, http://proxyjudge1.proxyfire.net/fastenv aufzurufen . Application_BeginRequest () bearbeitet diese Anfrage gerne. Wenn Sie also Request.Url.Host aufrufen, wenn diese Anfrage gestellt wird, erhalten Sie proxyjudge1.proxyfire.net zurück. Einige von Ihnen denken vielleicht "no duh", sind aber erwähnenswert, da es ein sehr schwerer Fehler war, ihn zu bemerken, da er nur in 0,1% der Fälle auftrat: P.

Dieser Fehler hat mich gezwungen, meinen Domain-Host als Zeichenfolge in die Konfigurationsdateien einzufügen.

Thirlan
quelle
Genau das Gleiche getan. Meine Domain befindet sich jetzt in web.config.
Korayem
Ich glaube, ich verstehe - warum schlägt Ihr Server Proxyfire? Ist das deine Seite? Insgesamt ist dies jedoch sinnvoll - die Verwendung eines anforderungsspezifischen Objekts während eines anwendungsspezifischen Ereignisses funktioniert möglicherweise nicht so gut. Besteht eine Gefahr in einem anforderungsspezifischen Ereignis, z. B. einem Seitenlebenszyklusereignis (Page.LoadCompleted usw.)?
mlhDev
Ich habe nicht zu genau nachgeforscht, warum es zu Proxyfire kam. Es war sicherlich nicht meine Seite, aber es zeigte mir, dass Current.Request.Url nicht 100% zuverlässig war. Nach vielen Recherchen hatte ich auch festgestellt, dass es nicht einfach ist, Ihren Hostnamen dynamisch zu bestimmen, da mehrere NIC-Karten, IPs und Domainnamen in dieselbe IP aufgelöst werden. Was deine andere Frage
betrifft,
Das ist also immer nur in Application_BeginRequest aufgetreten? Ich sehe nicht, wie IIS diese Anfrage jemals an Ihre App hätte senden können, wenn Sie vielleicht keinen Host-Header festgelegt haben.
Simon_Weaver
@Thirlan - Ich versuche, ein Problem zu debuggen, das ähnlich klingt. Ich versuche, die Subdomain mit Request.Url.Host abzurufen, und "normalerweise" funktioniert gut, aber nicht immer. Gibt es das überhaupt? Wie etwas anderes in der Anfrage, das richtig sein kann?
Scojomodena
14

Warum nicht verwenden

Request.Url.Authority

Es gibt die gesamte Domain UND den Port zurück.

Sie müssen noch http oder https berechnen

Korayem
quelle
2
Das funktioniert auch. Um http oder https zu "berechnen", setzen Sie einfach "//" davor. So würde es zum Beispiel lauten href = "// @ Request.Url.Authority ..."
EdwardM
2

Einfacher und kurzer Weg (es unterstützt Schema, Domäne und Port):

Verwenden 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
quelle
1

Ein anderer Weg:


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

quelle
Einfache aber einfach tolle Antwort!
Shiroy
1

Wie wäre es mit:

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
quelle
0

Verwenden von 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
quelle
-1

Wie wäre es mit:

String domain = "http://" + Request.Url.Host
jwalkerjr
quelle
Nicht schlecht, aber was ist, wenn Ihre Site sichere Seiten hat, dh https: // Was ist, wenn Ihre Domain nicht auf Port 80 gehostet wird?
Matt Mitchell