Quelle est la meilleure méthode dans ASP.NET pour obtenir le domaine actuel?

102

Je me demande quelle est la meilleure façon d'obtenir le domaine actuel dans ASP.NET?

Par exemple:

http://www.domainname.com/subdir/ doit renvoyer http://www.domainname.com http://www.sub.domainname.com/subdir/ doit renvoyer http://sub.domainname.com

À titre indicatif, je devrais pouvoir ajouter une URL comme "/Folder/Content/filename.html" (par exemple, généré par Url.RouteUrl () dans ASP.NET MVC) directement sur l'URL et cela devrait fonctionner.

Matt Mitchell
la source
3
Notez que le "domaine actuel" ici est en fait ce que l'agent utilisateur consommateur a utilisé pour accéder à votre site, qui dans de nombreux cas est différent de "l'URL officielle" de votre site ainsi que ce que l'utilisateur final a pu saisir dans son navigateur ( proxy inverse, proxy direct, nom d'hôte interne, adresse IP, ...).
bzlm
1
Alors, y a-t-il un moyen d'obtenir l '"URL officielle" (celle d'IIS?)
Matt Mitchell

Réponses:

186

Même réponse que celle de MattMitchell mais avec quelques modifications. Cela vérifie plutôt le port par défaut.

Edit: syntaxe mise à jour et utilisation Request.Url.Authoritycomme suggéré

$"{Request.Url.Scheme}{System.Uri.SchemeDelimiter}{Request.Url.Authority}"
Carlos Muñoz
la source
3
Y a-t-il un champ défini dans .NET, que je peux utiliser à la place de ":"? Quelque chose comme System.Uri.PortDelimiter? Vous savez, juste pour la cohérence. :)
Jan Aagaard
2
Pas que je sache, Jan Aagaard, mais vous pouvez toujours en faire un localement. Je fais cela pour la plupart des chaînes et des nombres "magiques". D'ailleurs, vous utiliseriez alors string.Empty au lieu de "" dans la réponse de Carlos;)
vbullinger
8
Vous pouvez utiliser Request.Url.Authoritycomme Korayem suggéré au lieu de Request.Url.Hostet Request.Url.Port.
Schmalls
4
Au lieu de concaténer des chaînes, vous devez utiliser la classe System.UriBuilder.
BrainSlugs83
3
@MattMitchell, il ne semble pas fonder les problèmes avec Authority, c'est l'équivalent de Host + ":" + Port, voir le code source dotnetframework.org/default.aspx/DotNET/DotNET/8@0/untmp/…
Giuseppe Romagnuolo
40

Selon ce lien, un bon point de départ est:

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

Cependant, si le domaine est http://www.domainname.com:500, cela échouera.

Quelque chose comme ce qui suit est tentant de résoudre ce problème:

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

Cependant, les ports 80 et 443 dépendront de la configuration.

En tant que tel, vous devez utiliser IsDefaultPortcomme dans la réponse acceptée ci-dessus de Carlos Muñoz.

Matt Mitchell
la source
1
Pourquoi supposer le port 80 ici? Si vous supprimez cette hypothèse, le code ressemble à un fourre-tout. Lorsque vous supposez le port 80, vous échouerez dans de nombreux scénarios (voir les commentaires sur d'autres réponses). Si vous souhaitez supprimer le numéro de port si possible, vous devez vérifier que le numéro de port est la valeur par défaut pour le schéma en question et que le schéma prend en charge les numéros de port par défaut.
bzlm le
Ouais voyez la note que le port 80 peut être une mauvaise idée. Je ne connais pas d'autre moyen de contourner cela, c'est pourquoi j'ai mentionné qu'il devra dépendre de la configuration.
Matt Mitchell
1
Je ne sais pas si cela aidera ou non, mais vous pouvez également essayer: si Request.IsSecureConnection pour déterminer si HTTPS est utilisé ou non?
Erick Brown
1
@EricBrown - Ouais, cette réponse n'est pas géniale en rétrospective 5 ans plus tard. J'irais avec la réponse acceptée de Carlos Muñoz pour éviter ce problème.
Matt Mitchell
29
Request.Url.GetLeftPart(UriPartial.Authority)

Ceci est inclus dans le schéma.

izlence
la source
23
J'aurais adoré être à la réunion quand ils ont trouvé ce nom
Simon_Weaver
20

AVERTISSEMENT! À toute personne qui utilise Current.Request .Url.Host. Comprenez que vous travaillez sur la base de la DEMANDE ACTUELLE et que la demande actuelle ne sera pas TOUJOURS avec votre serveur et peut parfois l'être avec d'autres serveurs.

Donc, si vous l'utilisez dans quelque chose comme Application_BeginRequest () dans Global.asax, alors 99,9% du temps, ça ira, mais 0,1% vous pourriez obtenir autre chose que le nom d'hôte de votre propre serveur.

Un bon exemple de ceci est quelque chose que j'ai découvert il n'y a pas longtemps. Mon serveur a tendance à frapper http://proxyjudge1.proxyfire.net/fastenv de temps en temps. Application_BeginRequest () gère volontiers cette requête, donc si vous appelez Request.Url.Host lors de cette requête, vous récupérerez proxyjudge1.proxyfire.net. Certains d'entre vous pensaient peut-être "non duh" mais il vaut la peine de le noter car c'était un bogue très difficile à remarquer car cela n'arrivait que 0,1% du temps: P

Ce bogue m'a obligé à insérer mon hôte de domaine sous forme de chaîne dans les fichiers de configuration.

Thirlan
la source
Fait exactement la même chose. Mon domaine est maintenant dans web.config.
Korayem
Je crois comprendre, cependant - pourquoi votre serveur rencontre-t-il proxyfire? Est-ce votre site? Mais, dans l'ensemble, cela a du sens - l'utilisation d'un objet spécifique à une demande lors d'un événement spécifique à une application peut ne pas fonctionner très bien. Y a-t-il un danger dans un événement spécifique à une demande, comme un événement du cycle de vie d'une page (Page.LoadCompleted, etc.)?
mlhDev
Je n'ai pas trop cherché à savoir pourquoi il se résolvait à proxyfire. Ce n'était certainement pas mon site, mais cela m'a indiqué que Current.Request.Url n'était pas fiable à 100%. Après de nombreuses recherches, j'avais également découvert que la détermination dynamique de votre nom d'hôte n'est pas facile, en raison de plusieurs cartes NIC, adresses IP et noms de domaine qui se résolvent sur la même adresse IP. Quant à votre autre question Matt, je ne suis pas sûr de ce que vous voulez dire: (
Thirlan
donc cela ne s'est jamais produit que dans Application_BeginRequest? Je ne vois pas comment IIS aurait pu envoyer cette demande à votre application à moins que vous n'ayez peut-être pas d'en-tête d'hôte défini?
Simon_Weaver
@Thirlan - J'essaie de déboguer un problème qui ressemble à celui-ci. J'essaie d'obtenir le sous-domaine en utilisant Request.Url.Host et fonctionne «généralement» bien, mais pas toujours. Y a-t-il vraiment de toute façon autour de cela? Comme quelque chose d'autre dans la demande qui peut être correct?
scojomodena
14

Pourquoi ne pas utiliser

Request.Url.Authority

Il renvoie le domaine entier ET le port.

Vous devez toujours comprendre http ou https

Korayem
la source
2
Cela fonctionne aussi. Pour "comprendre" http ou https, mettez simplement "//" devant lui. Ainsi, par exemple, il se lirait comme href = "// @ Request.Url.Authority ..."
EdwardM
2

Moyen simple et court (il prend en charge le schéma, le domaine et le port):

Utilisation 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
la source
1

Autrement:


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

la source
Réponse simple mais tout simplement géniale!
Shiroy
1

Que diriez-vous:

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
la source
0

Utilisation d'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
la source
-1

Que diriez-vous:

String domain = "http://" + Request.Url.Host
jwalkerjr
la source
Pas mal, mais que faire si votre site a des pages sécurisées ie https: // Et si votre domaine n'est pas hébergé sur le port 80?
Matt Mitchell