に基づく優れたソリューションがあり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 を動的に変更します