ASP.NET MVCのモデルでUrlHelperを呼び出す


159

ASP.NET MVCのモデルでいくつかのURLを生成する必要があります。ルートを使用してURLを生成するUrlHelper.Action()のようなものを呼び出したいのですが。ホスト名やスキームなど、通常の空白を埋めてもかまいません。

そのために呼び出すことができるメソッドはありますか?UrlHelperを構築する方法はありますか?


1
私はこれについて自分で考えていましたが、Url.Actionが相対URLを生成することに注意してください。それがあなたが望むものであることを確認してください。
ビビアン川

回答:


277

役立つヒント、ASP.NETアプリケーションでは、現在のHttpContextの参照を取得できます

HttpContext.Current

これはSystem.Webから派生しています。したがって、以下はASP.NET MVCアプリケーションのどこでも機能します。

UrlHelper url = new UrlHelper(HttpContext.Current.Request.RequestContext);
url.Action("ContactUs"); // Will output the proper link according to routing info

例:

public class MyModel
{
    public int ID { get; private set; }
    public string Link
    {
        get
        {
            UrlHelper url = new UrlHelper(HttpContext.Current.Request.RequestContext);
            return url.Action("ViewAction", "MyModelController", new { id = this.ID });
        }
    }

    public MyModel(int id)
    {
        this.ID = id;
    }
}

Link作成されたMyModelオブジェクトのプロパティを呼び出すと、Global.asaxのルーティングに基づいてモデルを表示するための有効なURLが返されます


HttpContext.Current.Request.RequestContextがあることを確認しますか?HttpContext.Current.RequestにRequestContextがないようです。
プペノ2010年

1
それは変です。私はこのソリューションをテストしたところ、完全に機能しました。ASP.NET MVC 2プレビュー2を実行していますが、これはすべてのバージョンで機能すると思います。なぜうまくいかないのかわからない。MVCプロジェクトの外部でクラスを作成していますか?またusing、両方にあることを確認System.WebしてくださいSystem.Web.Mvc
Omar

私はASP.NET MVC 1プロジェクトに参加しています。使用方法がないことを考えましたが、両方を使用しています。
プペノ2010年

なぜそれが表示されないのか本当にわからない。他の誰かがこれがASP.NET MVC 1に存在しないことを確認できれば、それはすばらしいことです。VS2010とMVC 2がインストールされているマシンは1台だけです。興味がある場合は、MVC RC 2 haacked.com/archive/2009/12/16/aspnetmvc-2-rc.aspx
Omar

6
Request.RequestContexが.NET4 +でサポートされていることに注意してください
h--n

64

私はオマールの答えが好きですが、それは私にとってはうまくいきません。参考までに、これは私が現在使用しているソリューションです。

var httpContext = HttpContext.Current;

if (httpContext == null) {
  var request = new HttpRequest("/", "http://example.com", "");
  var response = new HttpResponse(new StringWriter());
  httpContext = new HttpContext(request, response);
}

var httpContextBase = new HttpContextWrapper(httpContext);
var routeData = new RouteData();
var requestContext = new RequestContext(httpContextBase, routeData);

return new UrlHelper(requestContext);

私のサイトのURLが含まれています。そこで削除しました。
10

4
UrlHelperクラスが要求コンテキスト(およびHTTPコンテキスト)に依存していることを考慮すると、これらのコンテキストオブジェクトを手動で作成すると、予期しない結果が生じる可能性があります。HttpContext.Currentがnullであり、このアプローチを使用する場合は、注意して続行します。
Sean

4
この回答に注意してください。ダミーのRequestContextは、常に空の文字列を返すUrlHelperになります。
gknicker 2016年

47

UrlHelperは、以下を使用してコントローラーアクション内から構築できます。

 var url = new UrlHelper(this.ControllerContext.RequestContext);
 url.Action(...);

コントローラーの外では、RouteTable.Routes RouteDataからRequestContextを作成することにより、UrlHelperを構築できます。

HttpContextWrapper httpContextWrapper = new HttpContextWrapper(System.Web.HttpContext.Current);
UrlHelper urlHelper = new UrlHelper(new RequestContext(httpContextWrapper, RouteTable.Routes.GetRouteData(httpContextWrapper)));

(ブライアンの答えに基づいて、マイナーなコード修正が追加されています。)


2
しかし、モデルにはコントローラーがありません。
プペノ2010年

申し訳ありませんが、コードが実行されている正確な場所がわかりませんでした。見てみましょう...
ネイサンテイラー

2
新しい要求コンテキストを作成する必要がありません:var urlHelper = new UrlHelper(HttpContext.Current.Request.RequestContext);
bradlis7

素敵な@ bradlis7。それはMVC 5ですか?
Nathan Taylor

1
ので仕事は、しないthis.ControllerContext.RequestContextHttpRequestContextの、およびコンストラクタUrlHelperを期待RequestContext。両方のクラスは無関係です。
フロリアン冬

8

はい、インスタンス化できます。次のようなことができます:

var ctx = new HttpContextWrapper(HttpContext.Current);
UrlHelper helper = new UrlHelper(
   new RequestContext(ctx,
   RouteTable.Routes.GetRouteData(ctx));

RouteTable.Routes静的プロパティであるため、そこで大丈夫です。取得するにはHttpContextBase、参照を、HttpContextWrapperへの参照を取りHttpContext、そしてHttpContextそれを実現します。


これは非常に近いですが、機能しません。以下の私の答えを参照してください。
Nathan Taylor


0

ページ内(コントローラーの外部)から同様のことを実行しようとしました。

UrlHelperでは、Pablosが答えるほど簡単に構築できませんでしたが、同じことを効果的に行うための古いトリックを覚えていました。

string ResolveUrl(string pathWithTilde)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.