วิธีรับ URL หน้าปัจจุบันใน MVC 3


360

ฉันใช้ปลั๊กอินคอมเม้นท์ Facebook ในบล็อกที่ฉันกำลังสร้าง มันมีแท็ก FBXML บางส่วนที่ตีความโดย Javascript ของ Facebook ที่อ้างอิงในหน้านั้น

ทั้งหมดนี้ใช้ได้ดี แต่ฉันต้องผ่าน URL ที่ผ่านการรับรองโดยสมบูรณ์ไปยังปลั๊กอิน

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

วิธีที่ดีที่สุดในการรับ URL ของหน้าปัจจุบันคืออะไร? URL คำขอ

สารละลาย

นี่คือรหัสสุดท้ายของการแก้ปัญหาของฉัน:

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

คำตอบ:


533

คุณสามารถใช้Request.RawUrl, Request.Url.OriginalString, หรือRequest.Url.ToString()Request.Url.AbsoluteUri


2
ด้วยเหตุผลบางอย่างสิ่งนี้ดูเหมือนจะไม่ได้รับ URL ทั้งหมดทุกอย่างหลังจากโดเมน
Chev

6
@hevex วิธีการเกี่ยวกับRequest.Url.ToString()หรือRequest.Url.AbsoluteUri?
ดารินทร์ดิมิทรอฟ

9
เกือบจะ Request.Url.AbsoluteUriทำมัน :)
Chev

2
@Chevex - ไซต์ใดโฮสต์อยู่ ถ้าเป็นพอร์ต 80 แล้วใช่คุณจะไม่เห็นเลย ฉันบอกว่าในสภาพแวดล้อมที่มีการเผยแพร่เสมือน IP พอร์ต 80 หนึ่งหรือมากกว่าหนึ่งเครื่องในหนึ่งที่แตกต่างกันพอร์ต (เช่น 81) แล้ว Asp.Net มักจะเพิ่ม: 81 ไปยัง URL ไม่ถูกต้อง
Andras Zoltan

29
เพื่อรับตัวอย่างของชิ้นส่วน url ที่แตกต่างกันดูได้ที่: cambiaresearch.com/articles/53/…
ms007

48

เพิ่มวิธีการขยายนี้ในรหัสของคุณ:

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

และจากนั้นคุณสามารถดำเนินการได้ปิดRequestContext.HttpContext.Requestคุณสมบัติ

มีข้อผิดพลาด (สามารถก้าวด้านข้างดูด้านล่าง) ใน Asp.Net ที่เกิดขึ้นบนเครื่องที่ใช้พอร์ตอื่นที่ไม่ใช่พอร์ต 80 สำหรับเว็บไซต์ท้องถิ่น (เป็นปัญหาใหญ่หากเว็บไซต์ภายในเผยแพร่ผ่าน load-balancing บน IP เสมือน และพอร์ตจะใช้ภายในสำหรับการเผยแพร่กฎ) โดย Asp.Net จะเสมอเพิ่มพอร์ตในAbsoluteUriทรัพย์สิน - แม้ว่าคำขอเดิมไม่ได้ใช้มัน

รหัสนี้ทำให้มั่นใจได้ว่า url ที่ส่งคืนจะเท่ากับ Url ที่เบราว์เซอร์ร้องขอมาแต่แรก (รวมถึงพอร์ต - ซึ่งจะรวมอยู่ในส่วนหัวของโฮสต์) ก่อนที่จะมีการโหลดบาลานซ์ ฯลฯ

อย่างน้อยก็ทำในสภาพแวดล้อมของเรา (ค่อนข้างซับซ้อน!) :)

หากมีพร็อกซีขี้ขลาดใด ๆ ในระหว่างนั้นเขียนส่วนหัวของโฮสต์แล้วสิ่งนี้จะไม่ทำงานอย่างใดอย่างหนึ่ง

อัปเดต 30 กรกฎาคม 2556

ตามที่กล่าวถึงโดย @KevinJones ในความคิดเห็นด้านล่าง - การตั้งค่าที่ฉันพูดถึงในส่วนถัดไปได้รับการบันทึกไว้ที่นี่: http://msdn.microsoft.com/en-us/library/hh975440.aspx

แม้ว่าฉันจะต้องบอกว่าฉันไม่สามารถทำงานได้เมื่อฉันลอง - แต่นั่นอาจเป็นแค่ฉันพิมพ์ผิดหรือบางสิ่งบางอย่าง

อัปเดต 9 กรกฎาคม 2555

ฉันเจอเรื่องนี้เมื่อไม่นานมานี้และตั้งใจจะอัพเดตคำตอบนี้ แต่ไม่เคยทำ เมื่อ upvote เพิ่งมาในคำตอบนี้ฉันคิดว่าฉันควรทำตอนนี้

'ข้อผิดพลาด' ที่ฉันพูดถึงใน Asp.Net สามารถควบคุมได้ด้วยค่า appSettings ที่ไม่มีเอกสารซึ่งเรียกว่า'aspnet:UseHostHeaderForRequest'- เช่น -:

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

ฉันเจอสิ่งนี้ในขณะที่ดูHttpRequest.Urlใน ILSpy - ระบุโดย--->ด้านซ้ายของสำเนา / วางต่อไปนี้จากมุมมอง 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 */
       ...

ฉันเองไม่ได้ใช้มัน - มันไม่มีเอกสารและดังนั้นจึงไม่รับประกันว่าจะติด - แต่มันอาจทำในสิ่งเดียวกันกับที่ฉันได้กล่าวไว้ข้างต้น เพื่อเพิ่มความเกี่ยวข้องในผลการค้นหา - และเพื่อรับทราบคนอื่นที่เห็นว่าค้นพบสิ่งนี้ - การ'aspnet:UseHostHeaderForRequest'ตั้งค่าดังกล่าวได้รับการกล่าวถึงโดย Nick Aceves บน Twitter


ตกลงดังนั้นคุณจะได้รับอินสแตนซ์ของ HttpRequestBase จากที่ไหนหรืออย่างไรให้บอกว่าถ้าคุณไม่ได้ทำงานกับโค้ดโดยตรงในคอนโทรลเลอร์?
PositiveGuy

@ CoffeeAddict ดีใน mvc3 คุณมี HttpContext.Current.Request เนื่องจาก Asp.net 4 ใช้ abstractions พื้นฐาน หากใน. net 3.5 หรือต่ำกว่าคุณสามารถใช้ HttpRequestWrapper รอบ ๆ สถานที่ให้บริการเดียวกันจาก System.Web.Abstractions
Andras Zoltan

3
ดึกมากกับเรื่องนี้ แต่ UseHostHeaderForRequestUrl เป็นเอกสารที่นี่msdn.microsoft.com/en-us/library/hh975440.aspx
เควินโจนส์

จุดที่ดี! อย่างน้อยที่สุดพวกเขาก็เพิ่มไว้สำหรับเอกสาร 4.5!
Andras Zoltan


12
Request.Url.PathAndQuery

ควรทำงานได้อย่างสมบูรณ์โดยเฉพาะถ้าคุณต้องการให้ Uri ที่เป็นญาติ


8

ฉันก็กำลังมองหาสิ่งนี้ด้วยเหตุผลของ Facebook และไม่มีคำตอบใด ๆ ที่ให้มาเท่าที่จำเป็นหรือซับซ้อนเกินไป

@Request.Url.GetLeftPart(UriPartial.Path)

รับโปรโตคอลโฮสต์และพา ธ แบบเต็ม "โดยไม่มี" การสอบถาม รวมถึงพอร์ตด้วยหากคุณใช้อย่างอื่นที่ไม่ใช่ 80 ดีฟอลต์


เยี่ยมมาก! ฉันสงสัยว่าสิ่งนี้ไม่มีอยู่ในเวลาที่ถาม? ฉันรู้สึกว่าฉันจะได้เห็น :) :)
Chev

ฉันคิดว่าฉันเห็นที่นี่เพิ่งเพิ่ม แต่ฉันเพิ่งตรวจสอบและดูเหมือนว่ามันมีตั้งแต่. NET 1.1 ใครจะรู้.
johnw182

4

ของโปรด...

Url.Content(Request.Url.PathAndQuery)

หรือเพียงแค่ ...

Url.Action()

Url.Action () ให้เฉพาะด้านขวาของ url เท่านั้นหากคุณต้องการ URL แบบเต็ม
Alok

1

สิ่งหนึ่งที่ไม่ได้กล่าวถึงในคำตอบอื่น ๆ คือการพิจารณาตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ถ้ามันจะถูกอ้างอิงในหลาย ๆ ที่ (ซึ่งไม่ได้อยู่ในคำถามเดิม แต่มีค่าควรพิจารณาเมื่อคำถามนี้ปรากฏในการค้นหาที่คล้ายกันจำนวนมาก ) จากคำตอบอื่น ๆ ฉันพบว่าสิ่งต่อไปนี้ใช้ได้สำหรับฉันในตอนแรก:

Request.Url.AbsoluteUri.ToString()

แต่เพื่อให้มีความน่าเชื่อถือมากกว่านี้จึงกลายเป็น:

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

จากนั้นสำหรับความต้องการของฉัน (ตรวจสอบชื่อโดเมนที่ไซต์กำลังเข้าถึงและแสดงเนื้อหาที่เกี่ยวข้อง):

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


แต่นั่นไม่ได้ทำให้ "น่าเชื่อถือมากขึ้น" การลดขนาดมันจะมีประโยชน์ขึ้นอยู่กับสิ่งที่คุณพยายามทำจริง ๆ หรือไม่ โดยปกติแล้วคุณไม่ต้องการ URL ที่จะเป็นกรณีที่มีความอ่อนไหว
CodeCaster

1
@CodeCaster ใช่คำว่า 'เชื่อถือได้มากขึ้น' นั้นขึ้นอยู่กับประสบการณ์ของฉันเองเพราะฉันไม่ต้องการให้ URL เป็นตัวพิมพ์เล็กและใหญ่เพราะมันทำให้ลูกค้าไม่มีปัญหา
Lyall

0

สำหรับฉันปัญหาคือเมื่อฉันพยายามเข้าถึงHTTPContextในตัวสร้างของตัวควบคุมในขณะที่ยังHTTPContextไม่พร้อม เมื่อย้ายภายในวิธีดัชนีมันทำงาน:

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.