MVC 3で現在のページのURLを取得する方法


360

作成中のブログでFacebookコメントプラグインを使用しています。これには、ページで参照されているFacebookのJavaScriptによって解釈されるいくつかのFBXMLタグがあります。

これはすべて正常に機能しますが、現在の完全修飾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.RawUrlRequest.Url.OriginalStringRequest.Url.ToString()またはRequest.Url.AbsoluteUri


2
何らかの理由で、これはURL全体ではなく、ドメイン以降のすべてを取得しているようです。
Chev

6
@Chevex、いかがですRequest.Url.ToString()Request.Url.AbsoluteUri
Darin Dimitrov

9
ほとんど。Request.Url.AbsoluteUriそれをした:)
Chev

2
@Chevex-サイトがホストされているポートは何ですか?ポート80の場合は、はい、表示されません。別のポート(81など)の1つまたは複数のマシンへの仮想IP発行ポート80がある環境では、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プロパティから実行できます。

ローカルWebサイトにポート80以外のポートを使用するマシンで発生するAsp.Netにバグ(サイドステップされる可能性があります。以下を参照)があります(内部IPサイトが仮想IPの負荷分散を介して公開されている場合、大きな問題になります)およびポートは公開ルールに内部的に使用されます)。これにより、Asp.Netは常にAbsoluteUriプロパティにポートを追加します-元のリクエストがポートを使用しない場合でも。

このコードは、ロードバランシングなどが行われる前に、返されるURLがブラウザーが最初に要求したURL (ホストヘッダーに含まれるため、ポートを含む)と常に等しいことを保証します。

少なくとも、それは私たちの(かなり複雑です!)環境で行います:)

その間にホストヘッダーを書き換えるファンキーなプロキシがある場合、これも機能しません。

2013年7月30日更新

下のコメントで@KevinJonesで述べたように-設定私はここで報告されている次のセクションで言及:http://msdn.microsoft.com/en-us/library/hh975440.aspx

試してみたがうまくいかなかったと言わざるを得ないが、それはタイプミスか何かを作っているだけかもしれない。

2012年7月9日更新

私は少し前にこれに出くわしました、そしてこの答えを更新するつもりでした、しかし決してしませんでした。この回答について賛成票が入ってきたとき、今すぐやるべきだと思いました。

私がAsp.Netで言及している「バグ」は、明らかに文書化されていないappSettings値-と呼ばれる'aspnet:UseHostHeaderForRequest'- で制御できます。

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

HttpRequest.UrlILSpyで見ているときにこれに遭遇しました- --->その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'


わかりましたので、HttpRequestBaseのmanインスタンスをどこでどのように取得していますか?たとえば、コントローラーで直接コードを操作していない場合は、
PositiveGuy

@CoffeeAddictまあ、Mvc3ではHttpContext.Current.Requestがあります。Asp.net4はベースの抽象化を使用しているためです。.net 3.5以下の場合、System.Web.Abstractionsから同じプロパティの周りにHttpRequestWrapperを使用できます
Andras Zoltan

3
これにはかなり遅れますが、UseHostHeaderForRequestUrlはここにドキュメント化されていますmsdn.microsoft.com/en-us/library/hh975440.aspx
Kevin Jones

良い場所!少なくとも、ついに4.5ドキュメントに追加されました!
Andras Zoltan 2012


12
Request.Url.PathAndQuery

特に相対Uriのみが必要な場合(ただし、クエリ文字列を保持する場合)は、完全に機能するはずです。


8

私もFacebookの理由でこれを探していましたが、これまでに出された回答はいずれも必要に応じて機能しなかった、または複雑すぎました。

@Request.Url.GetLeftPart(UriPartial.Path)

完全なプロトコル、ホスト、およびクエリ文字列なしのパスを取得します。デフォルトの80以外を使用している場合は、ポートも含まれます。


素晴らしい発見!これは、質問した時点では存在していなかったのではないでしょうか。私はそれを見たように思います:)
Chev

これが追加されたところを見たと思っていましたが、チェックしたところ、.NET 1.1以降に存在しているようです。知るか。
johnw182 2015

4

お気に入り...

Url.Content(Request.Url.PathAndQuery)

あるいは単に...

Url.Action()

Url.Action()はURLの右側のみを提供しますが、完全な完全URLが必要な場合はどうなりますか?
2017

1

他の回答で言及されていないことの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でした。Indexメソッド内に移動すると、機能しました。

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.