Как получить URL текущей страницы в MVC 3

285

Я использую плагин комментариев Facebook в блоге, который я создаю. В нем есть теги FBXML, которые интерпретируются фреймворком javascript, на который ссылаются на странице.

Все работает отлично, но я должен передать текущий, полностью квалифицированный 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>
Теги:
razor
asp.net-mvc

8 ответов

443
Лучший ответ

Вы можете использовать Request.RawUrl, Request.Url.OriginalString, Request.Url.ToString() или Request.Url.AbsoluteUri.

  • 2
    По какой-то причине, кажется, что не весь URL, а только все после домена.
  • 6
    @Chevex, а как насчет Request.Url.ToString() или Request.Url.AbsoluteUri ?
Показать ещё 10 комментариев
45

Добавьте этот код расширения в свой код:

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, для локального веб-сайта (большая проблема, если внутренние веб-сайты публикуются с помощью балансировки нагрузки на виртуальном IP и порты используются для публикации правил), в результате чего Asp.Net всегда будет добавлять порт в свойство AbsoluteUri, даже если исходный запрос не использует его.

Этот код гарантирует, что возвращаемый url всегда равен Url, который первоначально запрашивал браузер (включая порт - как он был бы включен в заголовок хоста) до того, как будет выполняться балансировка нагрузки и т.д.

По крайней мере, это происходит в нашей (довольно запутанной!) среде:)

Если между переписыванием заголовка хоста есть какие-то фанковые прокси, то это тоже не сработает.

Обновление 30 июля 2013 года

Как упоминалось в комментариях @KevinJones в комментариях ниже - описанная здесь установка в следующем разделе описана здесь: http://msdn.microsoft.com/en-us/library/hh975440.aspx

Хотя я должен сказать, что не мог заставить его работать, когда я его пробовал, но это может быть просто опечатка или что-то в этом роде.

Обновление от 9 июля 2012 г.

Я наткнулся на это некоторое время назад и решил обновить этот ответ, но так и не сделал. Когда на этот ответ пришел ответ, я подумал, что должен сделать это сейчас.

"Ошибка", которую я упоминаю в Asp.Net, можно контролировать с явно недокументированным значением appSettings - 'aspnet:UseHostHeaderForRequest' - i.e:

<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' также упоминался Ником Асевесом в Twitter

  • 0
    Хорошо, так где или как вы получаете экземпляр man HttpRequestBase, скажем, если вы, например, не работали с кодом непосредственно в контроллере?
  • 0
    @CoffeeAddict Ну, в mvc3 у вас есть HttpContext.Current.Request, поскольку Asp.net 4 использует базовые абстракции. Если на .net 3.5 или ниже, вы можете использовать HttpRequestWrapper вокруг того же свойства, из System.Web.Abstractions
Показать ещё 3 комментария
10
public static string GetCurrentWebsiteRoot()
{
    return HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority);
}
8

Я тоже искал это по причинам Facebook, и ни один из ответов, которые были до сих пор не обработаны по мере необходимости или слишком сложны.

@Request.Url.GetLeftPart(UriPartial.Path)

Получает полный протокол, хост и путь "без" запроса. Также включает порт, если вы используете что-то отличное от 80 по умолчанию.

  • 0
    Отличная находка! Я подозреваю, что это не существовало во время запроса? Я чувствую, что видел бы это :)
  • 0
    Я думал, что видел, где это было только что добавлено, но я только что проверил, и кажется, что это было с .NET 1.1. Кто знает.
8
Request.Url.PathAndQuery

должен работать отлично, особенно если вы хотите только относительный Uri (но сохраняя повторяющиеся запросы)

  • 0
    Это было идеально для меня. Благодарю.
1

Мой любимый...

Url.Content(Request.Url.PathAndQuery)

или просто...

Url.Action()
  • 0
    Url.Action () предоставляет только правую часть URL, что если вам нужен полный полный URL?
0

Для меня проблема заключалась в том, что я пытался получить доступ к HTTPContext в конструкторе Controller, пока HTTPContext еще не готов. При перемещении внутри метода индекса он работал:

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

Одна вещь, которая не упоминается в других ответах, - это чувствительность к регистру, если она будет упоминаться в нескольких местах (что не в исходном вопросе, но стоит учитывать, так как этот вопрос появляется во многом аналогичных поисков). Основываясь на других ответах, я обнаружил, что сначала я работал у меня:

Request.Url.AbsoluteUri.ToString()

Но для того, чтобы быть более надежным, это стало следующим:

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

И затем для моих требований (проверяя, с каким доменным именем открывается сайт и показывая соответствующий контент):

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

  • 0
    Это не делает его «более надежным». Полезно ли использовать нижний регистр, полностью зависит от того, что вы на самом деле пытаетесь сделать, и почему чувствительность к регистру имеет смысл там. Обычно вы хотите, чтобы URL был чувствительным к регистру.
  • 1
    @CodeCaster Да, термин «более надежный» был основан на моем собственном опыте, так как я определенно НЕ хочу, чтобы URL-адреса были чувствительными к регистру, так как это не создает никаких проблем для клиентов.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню