Cara mendapatkan URL halaman saat ini di MVC 3

360

Saya menggunakan plugin komentar Facebook di blog yang saya buat. Ini memiliki beberapa tag FBXML yang ditafsirkan oleh javascript facebook yang dirujuk pada halaman.

Ini semua berfungsi dengan baik, tetapi saya harus meneruskan URL yang saat ini memenuhi syarat ke 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>

Apa cara terbaik untuk mendapatkan URL halaman saat ini? URL permintaan.

Larutan

Ini kode terakhir dari solusi saya:

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

Jawaban:

533

Anda bisa menggunakan Request.RawUrl, Request.Url.OriginalString, Request.Url.ToString()atau Request.Url.AbsoluteUri.

Darin Dimitrov
sumber
2
Untuk beberapa alasan, ini sepertinya tidak mendapatkan seluruh URL, hanya semuanya setelah domain.
Chev
6
@Chevex, bagaimana Request.Url.ToString()atau Request.Url.AbsoluteUri?
Darin Dimitrov
9
Hampir. Request.Url.AbsoluteUrimelakukannya :)
Chev
2
@Chevex - port apa yang dihosting oleh situs? Jika port 80 maka, ya, Anda tidak akan melihatnya. Saya mengatakan bahwa dalam lingkungan di mana ada port penerbitan IP virtual 80 ke satu atau lebih mesin pada port yang berbeda (mis. 81) maka Asp.Net akan selalu menambahkan: 81 ke Url secara salah
Andras Zoltan
29
untuk mendapatkan sampel dari fragmen url yang berbeda, lihat: cambiaresearch.com/articles/53/…
ms007
48

Tambahkan metode ekstensi ini ke kode Anda:

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

Dan kemudian Anda dapat menjalankannya RequestContext.HttpContext.Request properti.

Ada bug (dapat digerakkan samping, lihat di bawah) di Asp.Net yang muncul pada mesin yang menggunakan port selain port 80 untuk situs web lokal (masalah besar jika situs web internal diterbitkan melalui load-balancing pada IP virtual dan port digunakan secara internal untuk aturan penerbitan) dimana Asp.Net akan selalu menambahkan port padaAbsoluteUri properti - bahkan jika permintaan asli tidak menggunakannya.

Kode ini memastikan bahwa url yang dikembalikan selalu sama dengan Url yang browser aslinya diminta (termasuk port - karena akan dimasukkan dalam header host) sebelum terjadi penyeimbangan beban, dll.

Setidaknya, itu terjadi di lingkungan kami (agak berbelit-belit!) :)

Jika ada proksi funky di antara yang menulis ulang header host, maka ini tidak akan berhasil.

Pembaruan 30 Juli 2013

Seperti yang disebutkan oleh @KevinJones dalam komentar di bawah - pengaturan yang saya sebutkan di bagian selanjutnya telah didokumentasikan di sini: http://msdn.microsoft.com/en-us/library/hh975440.aspx

Meskipun saya harus mengatakan saya tidak bisa membuatnya bekerja ketika saya mencobanya - tapi itu bisa saja saya membuat kesalahan ketik atau sesuatu.

Pembaruan 9 Juli 2012

Saya menemukan ini beberapa waktu yang lalu, dan bermaksud memperbarui jawaban ini, tetapi tidak pernah melakukannya. Ketika seorang upvote baru saja masuk pada jawaban ini saya pikir saya harus melakukannya sekarang.

'Bug' yang saya sebutkan di Asp.Net dapat dikontrol dengan nilai appSettings yang tampaknya tidak berdokumen - disebut 'aspnet:UseHostHeaderForRequest'- yaitu:

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

Saya menemukan ini sambil melihat HttpRequest.Urldalam ILSpy - ditunjukkan oleh --->di sebelah kiri copy / paste berikut dari tampilan 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 */
       ...

Saya pribadi belum menggunakannya - tidak terdokumentasi dan karenanya tidak dijamin untuk tetap - namun mungkin melakukan hal yang sama seperti yang saya sebutkan di atas. Untuk meningkatkan relevansi dalam hasil pencarian - dan untuk mengakui orang lain yang seeems telah menemukan ini - yang 'aspnet:UseHostHeaderForRequest'pengaturan juga telah disebutkan oleh Nick Aceves di Twitter

Andras Zoltan
sumber
ok jadi di mana atau bagaimana Anda mendapatkan turunan HttpRequestBase katakanlah jika Anda tidak bekerja dengan kode secara langsung di controller misalnya?
PositiveGuy
@CoffeeAddict Nah, di mvc3 Anda memiliki HttpContext.Current.Request, karena Asp.net 4 menggunakan abstraksi dasar. Jika pada .net 3.5 atau lebih rendah, Anda dapat menggunakan HttpRequestWrapper di sekitar properti yang sama, dari System.Web.Abstractions
Andras Zoltan
3
Sangat terlambat untuk hal ini tetapi UseHostHeaderForRequestUrl didokumentasikan di sini msdn.microsoft.com/en-us/library/hh975440.aspx
Kevin Jones
tempat yang bagus! setidaknya mereka akhirnya menambahkannya untuk 4,5 dokumentasi!
Andras Zoltan
14
public static string GetCurrentWebsiteRoot()
{
    return HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority);
}
Brian Ogden
sumber
12
Request.Url.PathAndQuery

harus bekerja dengan sempurna, terutama jika Anda hanya ingin Uri relatif (tetapi menjaga querystrings)

Lucius
sumber
8

Saya juga mencari ini untuk alasan Facebook dan tidak ada jawaban yang diberikan sejauh ini berfungsi sesuai kebutuhan atau terlalu rumit.

@Request.Url.GetLeftPart(UriPartial.Path)

Mendapat protokol, host dan path lengkap "tanpa" querystring. Juga termasuk porta jika Anda menggunakan sesuatu selain dari default 80.

johnw182
sumber
Great ditemukan! Saya menduga ini tidak ada pada saat bertanya? Saya merasa seperti akan melihatnya :)
Chev
Saya pikir saya melihat di mana ini baru saja ditambahkan tetapi saya baru saja memeriksa dan sepertinya sudah ada sejak. NET 1.1. Siapa tahu.
johnw182
4

Kesukaanku...

Url.Content(Request.Url.PathAndQuery)

atau hanya...

Url.Action()
Carter Medlin
sumber
Url.Action () hanya menyediakan sisi kanan url, bagaimana jika Anda memerlukan url penuh penuh?
Alok
1

Satu hal yang tidak disebutkan dalam jawaban lain adalah sensitivitas case, jika itu akan direferensikan di banyak tempat (yang tidak ada dalam pertanyaan asli tetapi layak dipertimbangkan karena pertanyaan ini muncul dalam banyak pencarian serupa ). Berdasarkan jawaban lain saya menemukan yang berikut ini bekerja untuk saya pada awalnya:

Request.Url.AbsoluteUri.ToString()

Tetapi agar lebih dapat diandalkan ini kemudian menjadi:

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

Dan kemudian untuk persyaratan saya (memeriksa dari mana nama domain situs itu diakses dan menunjukkan konten yang relevan):

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

Lyall
sumber
Itu tidak membuatnya "lebih dapat diandalkan". Apakah menggunakan huruf kecil itu bermanfaat tergantung sepenuhnya pada apa yang sebenarnya Anda coba lakukan, dan mengapa sensitivitas huruf masuk akal di sana. Biasanya Anda tidak ingin URL menjadi case-sensitive.
CodeCaster
1
@CodeCaster Ya istilah 'lebih dapat diandalkan' didasarkan pada pengalaman saya sendiri, karena saya pasti TIDAK ingin URL menjadi case case karena tidak menyebabkan masalah bagi klien.
Lyall
0

Bagi saya masalahnya adalah ketika saya mencoba mengakses HTTPContextkonstruktor Pengendali sementara HTTPContextbelum siap. Ketika dipindahkan ke dalam metode Indeks, itu berhasil:

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

Kasing (gaya halaman tunggal) untuk riwayat browser

HttpContext.Request.UrlReferrer
Hamit YILDIRIM
sumber