3

次のようなURLをマッピングする必要があります。

/ stock / Risk->StockRiskController.Index()

/ stock / Risk / attr->StockRiskController.Attr()

/ srock / Risk / chart->StockRiskController.Chart()

..。

/ bond / performance->BondPerformanceController.Index()

/ bond / performance / attr->BondPerformanceController.Attr()

/ bond / performance /chart-> BondPerformanceController.Chart() ..。

最初の部分は動的ですが列挙可能であり、2番目の部分には2つのオプション(リスク|パフォーマンス)しかありません。

今のところ私は2つの方法しか知りません:

  1. ControllerFactoryをカスタマイズしました(やり過ぎまたは複雑なようです)
  2. 列挙可能(醜い)であるため、すべての組み合わせをハードコーディングします。

routes.MapRouteこれを達成するために使用できますか?または他の便利な方法はありますか?

4

1 に答える 1

2

に基づく優れたソリューションがありIRouteConstraintます。まず、新しいルート マッピングを作成する必要があります。

routes.MapRoute(
  name: "PrefixedMap",
  url: "{prefix}/{body}/{action}/{id}",
  defaults: new { prefix = string.Empty, body = string.Empty
                    , action = "Index", id = string.Empty },
  constraints: new { lang = new MyRouteConstraint() }
);

次のステップは、制約を作成することです。上記のように関連性を確認する方法を紹介する前に、可能な値を持つ2つのリストですが、ロジックは調整できます

public class MyRouteConstraint : IRouteConstraint
{
  public readonly IList<string> ControllerPrefixes = new List<string> { "stock", "bond" };
  public readonly IList<string> ControllerBodies = new List<string> { "risk", "performance" };
  ...

そして今、必要に応じてルーティングを調整する Match メソッド

public bool Match(System.Web.HttpContextBase httpContext
      , Route route, string parameterName, RouteValueDictionary values
      , RouteDirection routeDirection)
{
    // for now skip the Url generation
    if (routeDirection.Equals(RouteDirection.UrlGeneration))
    {
        return false;
    }

    // try to find out our parameters
    string prefix = values["prefix"].ToString();
    string body = values["body"].ToString();

    var arePartsKnown =
        ControllerPrefixes.Contains(prefix, StringComparer.InvariantCultureIgnoreCase) &&
        ControllerBodies.Contains(body, StringComparer.InvariantCultureIgnoreCase);

    // not our case
    if (!arePartsKnown)
    {
        return false;
    }

    // change controller value
    values["controller"] = prefix + body;
    values.Remove("prefix");
    values.Remove("body");

    return true;
}

この方法をもっといじることができますが、概念は明確になっているはずです。

注:私はあなたのアプローチが好きです。場合によっては、ルーティングを拡張/調整してからコードに移動して「名前を修正」することがはるかに重要な場合があります。同様のソリューションがここで機能していました: RouteValueDictionary を動的に変更します

于 2012-11-28T14:12:26.503 に答える