web-dev-qa-db-fra.com

Comment obtenir l'URL de la page actuelle dans MVC 3

J'utilise le plug-in de commentaires Facebook sur un blog que je construis. Il contient des balises FBXML interprétées par le code JavaScript de Facebook référencé sur la page.

Tout cela fonctionne bien, mais je dois transmettre l'URL complète et qualifiée actuelle au plug-in.

<div style="width: 900px; margin: auto;">
    <div id="fb-root"></div>
    <fb:comments href="URL HERE" num_posts="10" width="900"></fb:comments>
</div>

Quel est le meilleur moyen d'obtenir l'URL de la page en cours? L'URL de la demande.

Solution

Voici le code final de ma solution:

<fb:comments href="@Request.Url.AbsoluteUri" num_posts="15" width="900"></fb:comments>
347
Chev

Vous pouvez utiliser le Request.RawUrl , Request.Url.OriginalString , Request.Url.ToString() ou _Request.Url.AbsoluteUri_.

516
Darin Dimitrov

Ajoutez cette méthode d'extension à votre code:

public static Uri UrlOriginal(this HttpRequestBase request)
{
  string hostHeader = request.Headers["Host"];

  return new Uri(string.Format("{0}://{1}{2}",
     request.Url.Scheme, 
     hostHeader, 
     request.RawUrl));
}

Et vous pouvez ensuite l'exécuter à partir de la propriété RequestContext.HttpContext.Request.

Il y a un bogue (peut être contourné, voir ci-dessous) dans Asp.Net qui survient sur des ordinateurs utilisant des ports autres que le port 80 pour le site Web local (un gros problème si les sites Web internes sont publiés via l'équilibrage de charge sur IP virtuelle et les ports sont utilisés en interne pour les règles de publication) moyennant lequel Asp.Net ajoutera toujours le port sur la propriété AbsoluteUri, même si la requête d'origine ne l'utilise pas.

Ce code garantit que l'URL renvoyée est toujours égale à l'URL demandée par le navigateur à l'origine (y compris le port car elle serait incluse dans l'en-tête de l'hôte) avant tout équilibrage de charge, etc. se déroule.

Au moins, cela se passe dans notre environnement (plutôt compliqué!) :)

S'il y a des procurations géniales entre qui réécrivent l'en-tête de l'hôte, cela ne fonctionnera pas non plus.

Mise à jour le 30 juillet 2013

Comme mentionné par @KevinJones dans les commentaires ci-dessous - le paramètre que je mentionne dans la section suivante a été documenté ici: http://msdn.Microsoft.com/en-us/library/hh975440.aspx

Bien que je dois dire que je ne pouvais pas le faire fonctionner quand je l’essayais - mais c’était peut-être juste moi qui faisais une faute de frappe ou quelque chose du genre.

Mise à jour du 9 juillet 2012

Je suis tombé sur cette question il y a quelque temps et je voulais mettre à jour cette réponse, mais je ne l'ai jamais fait. Quand un vote positif vient d'arriver sur cette réponse, j'ai pensé que je devrais le faire maintenant.

Le "bogue" mentionné dans Asp.Net peut être contrôlé avec une valeur appSettings apparemment non documentée - appelée 'aspnet:UseHostHeaderForRequest' - c'est-à-dire:

<appSettings>
  <add key="aspnet:UseHostHeaderForRequest" value="true" />
</appSettings>

Je suis tombé sur cela en regardant HttpRequest.Url dans ILSpy - indiqué par le ---> à gauche du copier/coller suivant de cette vue ILSpy:

public Uri Url
{
  get
  {
    if (this._url == null && this._wr != null)
    {
      string text = this.QueryStringText;
      if (!string.IsNullOrEmpty(text))
      {
        text = "?" + HttpEncoder.CollapsePercentUFromStringInternal(text, 
          this.QueryStringEncoding);
      }
 ---> if (AppSettings.UseHostHeaderForRequestUrl)
      {
        string knownRequestHeader = this._wr.GetKnownRequestHeader(28);
        try
        {
          if (!string.IsNullOrEmpty(knownRequestHeader))
          {
            this._url = new Uri(string.Concat(new string[]
            {
              this._wr.GetProtocol(),
              "://",
              knownRequestHeader,
              this.Path,
              text 
            }));
          }
        }
        catch (UriFormatException)
        { }
     }
     if (this._url == null) { /* build from server name and port */
       ...

Personnellement, je ne l'ai pas utilisé - il est sans papiers et donc non garanti - mais il pourrait faire la même chose que celle que j'ai mentionnée ci-dessus. Pour augmenter la pertinence des résultats de recherche - et pour reconnaître les autres qui pensent avoir découvert cela - le paramètre 'aspnet:UseHostHeaderForRequest' a également été mentionné par Nick Aceves sur Twitter

47
Andras Zoltan
public static string GetCurrentWebsiteRoot()
{
    return HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority);
}
13
Brian Ogden
Request.Url.PathAndQuery

devrait fonctionner parfaitement, surtout si vous ne voulez que le Uri relatif (en gardant les chaînes de requête)

11
Lucius

Moi aussi, je cherchais cela pour des raisons liées à Facebook et aucune des réponses données jusqu'à présent ne fonctionnait au besoin ou n'était trop compliquée.

@Request.Url.GetLeftPart(UriPartial.Path)

Obtient le protocole complet, l'hôte et le chemin "sans" la chaîne de requête. Inclut également le port si vous utilisez autre chose que le 80 par défaut.

8
johnw182

Mon préféré...

Url.Content(Request.Url.PathAndQuery)

ou juste...

Url.Action()
4
Carter Medlin

Une chose qui n'est pas mentionnée dans d'autres réponses est la sensibilité à la casse, si elle doit être référencée à plusieurs endroits (ce qui n'est pas dans la question d'origine mais mérite d'être pris en compte car cette question apparaît dans de nombreuses recherches similaires. ). Sur la base d’autres réponses, j’ai trouvé ce qui suit fonctionnait initialement pour moi:

Request.Url.AbsoluteUri.ToString()

Mais pour être plus fiable, ceci est alors devenu:

Request.Url.AbsoluteUri.ToString().ToLower()

Et puis pour mes besoins (vérifier quel nom de domaine le site est consulté et afficher le contenu pertinent):

Request.Url.AbsoluteUri.ToString().ToLower().Contains("xxxx")

1
Lyall

Le cas (style de page unique) pour l'historique du navigateur

HttpContext.Request.UrlReferrer
0
Hamit YILDIRIM

Pour moi, le problème était lorsque j'ai essayé d'accéder à HTTPContext dans le constructeur du contrôleur alors que HTTPContext n'était pas encore prêt. Quand déplacé à l'intérieur de la méthode Index cela a fonctionné:

var uri = new Uri(Request.Url.AbsoluteUri);
url = uri.Scheme + "://" + uri.Host + "/";enter code here
0
boateng