式ツリーを使用してDomainRouteのURLを構築する

6783 ワード

DomainRouteはURLドメイン名のキャプチャと構造をサポートしているため、ASP.NET Routingが作成した「プロトコル」(ASP.NET RoutingはPathのみをサポート)を破壊しているため、前の記事では、「ドメイン名を含む」URLを得るための補助方法を自分で構築する必要があります.しかし、できるだけ強いタイプの原則に基づいて、MvcFuturesで定義された式ツリーに基づく補助方法を使用する必要があります.MvcFuturesはすでに十分な補助機能を提供しているので、実際には私たちに多くの代価を払う必要はありません.
前回はこのような補助方法を書きました.
public static string ActionEx(this UrlHelper helper, string action, object routeValues)
{
    var values = routeValues == null ?
        new RouteValueDictionary() : 
        new RouteValueDictionary(routeValues);
    values.Add("action", action);
    values.Add("controller", helper.RequestContext.RouteData.Values["controller"]);

    return helper.GetRouteUrl(values);
}

private static string GetRouteUrl(this UrlHelper helper, RouteValueDictionary values)
{
    var pathData = helper.RouteCollection.GetPath(helper.RequestContext, values);
    var url = pathData.VirtualPath;
    return IsAbsolute(url) ? url : "/" + url;
}
しかし、必要に応じて、次のコードを作成する方法を考えなければなりません.
<a href="= Url.ActionEx<HomeController>(c => c.Index()) %>">Homea>
では、このActionExメソッドの署名はどのようなものなのでしょうか.1つのメソッドの呼び出し方式からその署名を導くことも,良好なAPIを構築するために必要な能力である.ここではActionExメソッドの署名を次のように決定できます.
public static string ActionEx(
    this UrlHelper helper, Expression<Action> action)
    where TController : Controller
{
    return ActionEx(helper, action, null);
}

public static string ActionEx(
    this UrlHelper helper, Expression<Action> action, object routeValues)
    where TController : Controller
{
    ...
}
従来のActionExメソッドとは異なり、従来のActionExメソッドは文字列を1つしか持っていなかったが、現在のactionは式ツリーであり、どのControllerのどのActionメソッドを呼び出し、どのパラメータを使用したかという多くの情報が含まれている.たとえば、最終的に生成されるURLは同じです.
= Url.ActionEx("List", new { controller = "Post", id = 5, area = "blogs" }) %>
= Url.ActionEx<PostController>(c => c.List(5), new { area = "blogs" }) %>
これにより、2つの状況で、さまざまな必要なデータがどのように伝達されているかがわかります.したがって、新しいActionExメソッドは、次のようになります.
public static string ActionEx(
    this UrlHelper helper, Expression<Action> action, object routeValues)
    where TController : Controller
{
    var values = GetRouteValuesFromExpression(action);
    if (routeValues != null)
    {
        values.CopyFrom(new RouteValueDictionary(routeValues));
    }

    return helper.GetRouteUrl(values);
}

private static RouteValueDictionary GetRouteValuesFromExpression(
    Expression<Action> action) where TController : Controller
{
    ...
}
ここで重要なのは、式ツリーからデータを抽出する方法(GetRouteValuesFromExpressionメソッドの実装)です.表現ツリーが分からない場合は、この点は少し難しいかもしれません.幸いなことに、実はMvcFuturesプロジェクトはすでに十分な補助機能を持っています.
private static RouteValueDictionary GetRouteValuesFromExpression(
    Expression<Action> action) where TController : Controller
{
    return ExpressionHelper.GetRouteValuesFromExpression(action);
}
これで、終わりです.もちろん、既存のMvcFuturesに欠けている機能や不足している機能も直接私たちのプロジェクトに持ち込まれています.次回はこれらの機能を改善します.