Come ottenere l'URL della pagina corrente in MVC 3


360

Sto usando il plugin dei commenti di Facebook su un blog che sto costruendo. Ha alcuni tag FBXML che sono interpretati dal javascript di Facebook a cui fa riferimento la pagina.

Funziona tutto bene, ma devo passare l'URL corrente e completo al 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>

Qual è il modo migliore per ottenere l'URL della pagina corrente? L'URL della richiesta.

Soluzione

Ecco il codice finale della mia soluzione:

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

Risposte:


533

È possibile utilizzare il Request.RawUrl, Request.Url.OriginalString, Request.Url.ToString()o Request.Url.AbsoluteUri.


2
Per qualche motivo, questo non sembra ottenere l'intero URL, ma tutto ciò che segue il dominio.
Chev,

6
@Chevex, che ne dici di Request.Url.ToString()o Request.Url.AbsoluteUri?
Darin Dimitrov,

9
Quasi. Request.Url.AbsoluteUrifatto :)
Chev,

2
@Chevex - su quale porta è ospitato il sito? Se è la porta 80, sì, non ne vedrai una. Sto dicendo che in un ambiente in cui esiste una porta di pubblicazione IP virtuale 80 su una o più macchine su un altro porta (es. 81), Asp.Net aggiungerà sempre: 81 all'URL in modo errato
Andras Zoltan

29
per ottenere campioni dei diversi frammenti di URL, dai un'occhiata a: cambiaresearch.com/articles/53/…
ms007

48

Aggiungi questo metodo di estensione al tuo codice:

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

E poi puoi eseguirlo fuori dalla RequestContext.HttpContext.Requestproprietà.

C'è un bug (può essere modificato, vedi sotto) in Asp.Net che si presenta su macchine che usano porte diverse dalla porta 80 per il sito Web locale (un grosso problema se i siti Web interni sono pubblicati tramite bilanciamento del carico su IP virtuale e le porte vengono utilizzate internamente per le regole di pubblicazione) in base alle quali Asp.Net aggiungerà sempre la porta sulla AbsoluteUriproprietà, anche se la richiesta originale non la utilizza.

Questo codice assicura che l'URL restituito sia sempre uguale all'URL originariamente richiesto dal browser (inclusa la porta - come verrebbe incluso nell'intestazione host) prima che avvenga qualsiasi bilanciamento del carico ecc.

Almeno, lo fa nel nostro ambiente (piuttosto contorto!) :)

Se ci sono dei proxy stravaganti tra questi che riscrivono l'intestazione host, allora non funzionerà neanche.

Aggiornamento del 30 luglio 2013

Come menzionato da @KevinJones nei commenti seguenti, l'impostazione che cito nella prossima sezione è stata documentata qui: http://msdn.microsoft.com/en-us/library/hh975440.aspx

Anche se devo dire che non riuscivo a farlo funzionare quando l'ho provato, ma potrei essere solo io a fare un refuso o qualcosa del genere.

Aggiornamento del 9 luglio 2012

L'ho trovato poco fa e intendevo aggiornare questa risposta, ma non l'ho mai fatto. Quando è arrivata una votazione su questa risposta, ho pensato che avrei dovuto farlo ora.

Il 'bug' che cito in Asp.Net può essere controllato con un valore appSettings apparentemente non documentato - chiamato 'aspnet:UseHostHeaderForRequest'- cioè:

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

Mi sono imbattuto in questo mentre guardavo HttpRequest.Urlin ILSpy - indicato dalla --->sinistra sulla seguente copia / incolla da quella vista 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 */
       ...

Personalmente non l'ho usato - è privo di documenti e quindi non è garantito che rimanga - tuttavia potrebbe fare la stessa cosa che ho menzionato sopra. Per aumentare la pertinenza nei risultati di ricerca - e riconoscere qualcun altro che sembra averlo scoperto - l' 'aspnet:UseHostHeaderForRequest'impostazione è stata citata anche da Nick Aceves su Twitter


ok quindi dove o come stai ottenendo l'istanza man di HttpRequestBase, per esempio, se non stavi lavorando con il codice direttamente in un controller?
Positivo

@CoffeeAddict Bene, in mvc3 hai HttpContext.Current.Request, poiché Asp.net 4 usa le astrazioni di base. Se su .net 3.5 o versioni precedenti, è possibile utilizzare HttpRequestWrapper attorno alla stessa proprietà, da System.Web.Abstractions
Andras Zoltan,

3
Molto tardi, ma UseHostHeaderForRequestUrl è documentato qui msdn.microsoft.com/en-us/library/hh975440.aspx
Kevin Jones,

buon posto! almeno l'hanno finalmente aggiunto per la documentazione 4.5!
Andras Zoltan,

14
public static string GetCurrentWebsiteRoot()
{
    return HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority);
}

12
Request.Url.PathAndQuery

dovrebbe funzionare perfettamente, soprattutto se si desidera solo l'Uri relativo (ma mantenendo le stringhe di querys)


8

Anch'io lo stavo cercando per motivi di Facebook e nessuna delle risposte fornite finora ha funzionato se necessario o sono troppo complicate.

@Request.Url.GetLeftPart(UriPartial.Path)

Ottiene l'intero protocollo, host e percorso "senza" la stringa di query. Include anche la porta se si utilizza qualcosa di diverso dall'80 predefinito.


Grande scoperta! Ho il sospetto che questo non esistesse al momento della domanda? Mi sento come se l'avessi visto :)
Chev,

Pensavo di aver visto dove era stato appena aggiunto, ma ho appena controllato e sembra che sia stato lì da .NET 1.1. Chissà.
johnw182,

4

Il mio preferito...

Url.Content(Request.Url.PathAndQuery)

o solo ...

Url.Action()

Url.Action () fornisce solo il lato destro dell'URL, cosa succede se hai bisogno dell'URL completo?
Aspetta il

1

Una cosa che non è menzionata in altre risposte è la distinzione tra maiuscole e minuscole, se verrà fatto riferimento in più punti (che non è nella domanda originale ma vale la pena prendere in considerazione poiché questa domanda appare in molte ricerche simili ). Sulla base di altre risposte, inizialmente ho riscontrato che per me ha funzionato:

Request.Url.AbsoluteUri.ToString()

Ma per essere più affidabile questo è diventato:

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

E poi per i miei requisiti (verificando da quale nome di dominio si accede al sito e mostrando il contenuto pertinente):

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


Ciò non lo rende "più affidabile". Se la riduzione in minuscolo sia utile dipende interamente da ciò che stai effettivamente cercando di fare e dal perché la sensibilità del case avrebbe senso lì. Di solito si fa desidera che l'URL sia maiuscole e minuscole.
CodeCaster

1
@CodeCaster Sì, il termine "più affidabile" si basava sulla mia esperienza personale, in quanto NON desidero assolutamente che gli URL facciano distinzione tra maiuscole e minuscole in quanto non causano problemi ai client.
Lyall,

0

Per me il problema era quando ho provato ad accedere HTTPContextal costruttore del Controller mentre HTTPContextnon è ancora pronto. Quando spostato all'interno del metodo Index ha funzionato:

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

0

Il caso (stile pagina singola) per la cronologia del browser

HttpContext.Request.UrlReferrer
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.