Cách nhận URL trang hiện tại trong MVC 3


360

Tôi đang sử dụng plugin bình luận Facebook trên một blog tôi đang xây dựng. Nó có một số thẻ FBXML được giải thích bởi javascript facebook được tham chiếu trên trang.

Tất cả đều hoạt động tốt, nhưng tôi phải chuyển URL hiện tại, đủ điều kiện cho 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>

Cách tốt nhất để có được URL của trang hiện tại là gì? URL yêu cầu.

Giải pháp

Đây là mã cuối cùng của giải pháp của tôi:

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

Câu trả lời:


533

Bạn có thể sử dụng Request.RawUrl, Request.Url.OriginalString, Request.Url.ToString()hoặc Request.Url.AbsoluteUri.


2
Vì một số lý do, điều này dường như không nhận được toàn bộ URL, chỉ là mọi thứ sau tên miền.
Chev

6
@Chevex, làm thế nào Request.Url.ToString()hoặc Request.Url.AbsoluteUri?
Darin Dimitrov

9
Hầu hết. Request.Url.AbsoluteUriđã làm điều đó :)
Chev

2
@Chevex - trang web được lưu trữ trên cổng nào? Nếu đó là cổng 80 thì có, bạn sẽ không thấy cái nào cả. Tôi đang nói rằng trong một môi trường có cổng xuất bản IP ảo 80 đến một hoặc nhiều máy trên một cổng khác (ví dụ 81) thì Asp.Net sẽ luôn thêm: 81 vào Url không chính xác
Andras Zoltan

29
để lấy mẫu của các đoạn url khác nhau, hãy xem: cambiaresearch.com/articles/53/iêu
ms007

48

Thêm phương thức mở rộng này vào mã của bạn:

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

Và sau đó bạn có thể thực hiện nó ra khỏi RequestContext.HttpContext.Requesttài sản.

Có một lỗi (có thể được đặt bên cạnh, xem bên dưới) trong Asp.Net phát sinh trên các máy sử dụng cổng ngoài cổng 80 cho trang web cục bộ (một vấn đề lớn nếu các trang web nội bộ được xuất bản thông qua cân bằng tải trên IP ảo và các cổng được sử dụng nội bộ cho các quy tắc xuất bản), theo đó Asp.Net sẽ luôn thêm cổng trên thuộc AbsoluteUritính - ngay cả khi yêu cầu ban đầu không sử dụng nó.

Mã này đảm bảo rằng url được trả về luôn bằng với Url mà trình duyệt yêu cầu ban đầu (bao gồm cả cổng - vì nó sẽ được bao gồm trong tiêu đề máy chủ) trước khi xảy ra bất kỳ cân bằng tải nào.

Ít nhất, nó làm trong môi trường (khá phức tạp!) Của chúng tôi :)

Nếu có bất kỳ proxy thú vị nào ở giữa đó viết lại tiêu đề máy chủ, thì điều này cũng không hoạt động.

Cập nhật ngày 30 tháng 7 năm 2013

Như được đề cập bởi @KevinJones trong các bình luận bên dưới - cài đặt tôi đề cập trong phần tiếp theo đã được ghi lại ở đây: http://msdn.microsoft.com/en-us/l Library / hh975440.aspx

Mặc dù tôi phải nói rằng tôi không thể làm cho nó hoạt động khi tôi thử nó - nhưng đó chỉ có thể là tôi mắc lỗi đánh máy hoặc một cái gì đó.

Cập nhật ngày 9 tháng 7 năm 2012

Tôi đã bắt gặp điều này một chút trước đây, và có nghĩa là để cập nhật câu trả lời này, nhưng không bao giờ làm. Khi một upvote vừa xuất hiện trong câu trả lời này, tôi nghĩ rằng tôi nên làm điều đó ngay bây giờ.

'Lỗi' tôi đề cập trong Asp.Net có thể được kiểm soát bằng giá trị cài đặt ứng dụng rõ ràng không có giấy tờ - được gọi là 'aspnet:UseHostHeaderForRequest'- tức là:

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

Tôi đã bắt gặp điều này trong khi xem xét HttpRequest.Urltrong ILSpy - được biểu thị bằng --->bên trái của bản sao / dán sau đây từ chế độ xem 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 */
       ...

Cá nhân tôi đã không sử dụng nó - nó không có giấy tờ và do đó không được bảo đảm để dính xung quanh - tuy nhiên nó có thể làm điều tương tự mà tôi đã đề cập ở trên. Để tăng tính thích hợp trong kết quả tìm kiếm - và thừa nhận người khác người seeems đã phát hiện ra này - các 'aspnet:UseHostHeaderForRequest'thiết lập cũng đã được đề cập bởi Nick Aceves trên Twitter


ok vậy bạn lấy ví dụ về httpRequestBase ở đâu hoặc bằng cách nào nếu bạn không làm việc với mã trực tiếp trong bộ điều khiển chẳng hạn?
Tích cực,

@CoffeeAddict Vâng, trong mvc3, bạn có HttpContext.Cản.Request, vì Asp.net 4 sử dụng các tóm tắt cơ bản. Nếu trên .net 3.5 trở xuống, bạn có thể sử dụng HttpRequestWrapper xung quanh cùng một thuộc tính, từ System.Web.Abstrilities
Andras Zoltan

3
Rất muộn với điều này nhưng UsehostHeaderForRequestUrl được ghi lại ở đây msdn.microsoft.com/en-us/l
Kevin Jones

điểm tốt! ít nhất cuối cùng họ đã thêm nó cho tài liệu 4.5!
Andras Zoltan

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

12
Request.Url.PathAndQuery

nên hoạt động hoàn hảo, đặc biệt nếu bạn chỉ muốn Uri tương đối (nhưng vẫn giữ truy vấn)


8

Tôi cũng đang tìm kiếm điều này vì lý do Facebook và không có câu trả lời nào được đưa ra cho đến nay cần thiết hoặc quá phức tạp.

@Request.Url.GetLeftPart(UriPartial.Path)

Nhận đầy đủ giao thức, máy chủ và đường dẫn "không có" chuỗi truy vấn. Cũng bao gồm cổng nếu bạn đang sử dụng một cái gì đó ngoài 80 mặc định.


Tuyệt vời tìm thấy! Tôi nghi ngờ điều này không tồn tại tại thời điểm hỏi? Tôi cảm thấy như tôi đã thấy rằng :)
Chev

Tôi nghĩ rằng tôi đã thấy nơi này vừa được thêm nhưng tôi chỉ kiểm tra và có vẻ như nó đã ở đó kể từ .NET 1.1. Ai biết.
johnw182

4

Sở thích của tôi ...

Url.Content(Request.Url.PathAndQuery)

hoặc chỉ ...

Url.Action()

Url.Action () chỉ cung cấp bên phải url, nếu bạn cần url đầy đủ thì sao?
Alok

1

Một điều không được đề cập trong các câu trả lời khác là phân biệt chữ hoa chữ thường, nếu nó sẽ được tham chiếu ở nhiều nơi (điều này không có trong câu hỏi ban đầu nhưng đáng để xem xét vì câu hỏi này xuất hiện trong rất nhiều tìm kiếm tương tự ). Dựa trên các câu trả lời khác, tôi thấy những điều sau đây có hiệu quả với tôi ban đầu:

Request.Url.AbsoluteUri.ToString()

Nhưng để đáng tin cậy hơn thì điều này đã trở thành:

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

Và sau đó cho các yêu cầu của tôi (kiểm tra tên miền nào trang web đang được truy cập và hiển thị nội dung có liên quan):

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


Điều đó không làm cho nó "đáng tin cậy hơn". Việc hạ thấp nó có hữu ích hay không hoàn toàn phụ thuộc vào những gì bạn thực sự đang cố gắng thực hiện và tại sao phân biệt chữ hoa chữ thường sẽ có ý nghĩa ở đó. Thông thường, bạn làm muốn URL là trường hợp nhạy cảm.
CodeCaster

1
@CodeCaster Vâng, thuật ngữ 'đáng tin cậy hơn' dựa trên kinh nghiệm của riêng tôi, vì tôi chắc chắn KHÔNG muốn các URL phải phân biệt chữ hoa chữ thường vì nó không gây ra sự cố cho khách hàng.
Lyall

0

Đối với tôi, vấn đề là khi tôi cố truy cập HTTPContextvào hàm tạo của Trình điều khiển trong khi HTTPContextchưa sẵn sàng. Khi được di chuyển bên trong phương thức Index, nó hoạt động:

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

0

Trường hợp (kiểu trang đơn) cho lịch sử trình duyệt

HttpContext.Request.UrlReferrer
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.