382 votes

Comment obtenir l'URL de la page en cours dans MVC 3

J'utilise le plugin "Commentaires Facebook" sur un blog que je suis en train de créer. Il comporte des balises FBXML qui sont interprétées par le javascript Facebook référencé sur la page.

Tout cela fonctionne bien, mais je dois transmettre l'URL actuelle, entièrement qualifiée, au plugin.

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

Quelle est la meilleure façon d'obtenir l'URL de la page actuelle ? L'URL de la requête.

Solution

Voici le code final de ma solution :

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

554voto

Darin Dimitrov Points 528142

Vous pourriez utiliser le Request.RawUrl , Request.Url.OriginalString , Request.Url.ToString() o Request.Url.AbsoluteUri .

3 votes

Pour une raison quelconque, cela ne semble pas récupérer l'intégralité de l'URL, juste tout ce qui suit le domaine.

6 votes

@Chevex, que diriez-vous de Request.Url.ToString() o Request.Url.AbsoluteUri ?

0 votes

Notez que Request.RawUrl et Request.Url peuvent être différents si l'Url a été réécrite.

49voto

Andras Zoltan Points 24996

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 ensuite vous pouvez l'exécuter à partir du RequestContext.HttpContext.Request propriété.

Il existe un bogue (qui peut être contourné, voir ci-dessous) dans Asp.Net qui se produit sur les machines qui utilisent des ports autres que le port 80 pour le site web local (un problème important si les sites web internes sont publiés via l'équilibrage de charge sur l'IP virtuelle et que les ports sont utilisés en interne pour les règles de publication). toujours ajouter le port sur le AbsoluteUri même si la demande originale ne l'utilise pas.

Ce code garantit que l'url retournée est toujours égale à l'url du navigateur. à l'origine demandé (y compris le port - comme il serait inclus dans l'en-tête de l'hôte) avant tout équilibrage de charge, etc.

Du moins, c'est le cas dans notre environnement (plutôt alambiqué !) :)

S'il existe entre les deux des proxies qui réécrivent l'en-tête de l'hôte, cela ne fonctionnera pas non plus.

Mise à jour du 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 doive dire que je n'ai pas réussi à le faire fonctionner quand je l'ai essayé - mais cela pourrait juste être une faute de frappe ou autre.

Mise à jour du 9 juillet 2012

Je suis tombé sur ce sujet il y a quelque temps, et j'avais l'intention de mettre à jour cette réponse, mais je ne l'ai jamais fait. Quand un vote positif est arrivé sur cette réponse, j'ai pensé que je devais le faire maintenant.

Le "bug" que je mentionne 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 ceci en regardant HttpRequest.Url dans ILSpy - indiqué par l'icône ---> à 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 */
       ...

Je ne l'ai personnellement pas utilisé - il n'est pas documenté et n'est donc pas garanti de rester en place - mais il pourrait faire la même chose que ce que je mentionne ci-dessus. Pour augmenter la pertinence dans les résultats de recherche - et pour remercier quelqu'un d'autre qui semble l'avoir découvert - je vous invite à consulter la page suivante. el 'aspnet:UseHostHeaderForRequest' setting a également été mentionné par Nick Aceves sur Twitter

0 votes

Ok alors où ou comment obtenez-vous une instance de HttpRequestBase si vous ne travaillez pas avec du code directement dans un contrôleur par exemple ?

0 votes

@CoffeeAddict Eh bien, dans mvc3 vous avez HttpContext.Current.Request, puisque Asp.net 4 utilise les abstractions de base. Si vous êtes sur .net 3.5 ou inférieur, vous pouvez utiliser HttpRequestWrapper autour de la même propriété, depuis System.Web.Abstractions

3 votes

Très tardivement, mais le UseHostHeaderForRequestUrl est documenté ici. msdn.microsoft.com/fr/us/library/hh975440.aspx

15voto

Brian Ogden Points 1954
public static string GetCurrentWebsiteRoot()
{
    return HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority);
}

14voto

Lucius Points 410
Request.Url.PathAndQuery

devrait fonctionner parfaitement, surtout si vous ne voulez que l'Uri relatif (tout en conservant les querystrings).

9voto

johnw182 Points 314

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

@Request.Url.GetLeftPart(UriPartial.Path)

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X