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.


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}"

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.


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.


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.


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


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

1

Autrement:


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

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

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

-1

Que diriez-vous:

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

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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.