web-dev-qa-db-ja.com

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

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

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

154
pupeno

私はオマールの答えが好きですが、それは私のために働いていません。記録のために、これは私が現在使用しているソリューションです:

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);
64
pupeno

役に立つヒント、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;
    }
}

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

274
Omar

UrlHelperは、次を使用してControllerアクション内から構築できます。

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

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

43
Nathan Taylor

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

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

RouteTable.Routesは静的プロパティであるため、そこに問題はありません。 HttpContextBase参照を取得するには、HttpContextWrapperHttpContextへの参照を取得し、HttpContextがそれを配信します。

8
Brian Mains

他のすべての答えを試した後、私は

$"/api/Things/Action/{id}"

嫌いは嫌いだ¯\ _(ツ)_ /¯

2
Florian Winter

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

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

string ResolveUrl(string pathWithTilde)
0
vGHazard