この質問のフォローアップとしてRouteValueDictionary
、特定のルートを動的に変更するために、カスタム ルート制約を実装しようとしています。
私はそこまでの道のりの 95% です。URL で指定されたアクションに一致する指定されたパラメーター パターンに基づいて、任意のルートを一致させることができます。このプロセスの最後のステップは、RouteValueDictionary を上書きして、コントローラー アクションの適切なパラメーターとしてキーの名前を変更することです。
これが私のコードの関連するスニペットです(クラス全体はほぼ300行なので、すべてを追加したくはありませんが、必要に応じて追加できます):
public class CustomRouteConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string paramName, RouteValueDictionary values, RouteDirection routeDirection)
{
if (routeDirection.Equals(RouteDirection.UrlGeneration)) {
return false;
}
//this will grab all of the "actual" parameters out of the RVD, excluding action and controller
Dictionary<string, object> unMappedList = values.Where(x => x.Key.Contains("param")).OrderBy(xi => xi.Key).ToDictionary(
kvp => kvp.Key, kvp => kvp.Value);
string controller = values["controller"] as string;
string action = values["action"] as string;
//this method tries to find the controller using reflection
Type cont = TryFindController(controller);
if (cont != null) {
MethodInfo actionMethod = cont.GetMethod(action);
if (actionMethod != null) {
ParameterInfo[] methodParameters = actionMethod.GetParameters();
//this method validates that the parameters of the action that was found match the expected parameters passed in the custom constraint; it also performs type conversion
if (validateParameters(methodParameters, unMappedList)) {
for (int i = 0; i < methodParameters.Length; i++) {
values.First(x => x.Key == unMappedList.ElementAt(i).Key).Key = methodParameters.ElementAt(i).Name;
//above doesn't work, but even if it did it wouldn't do the right thing
return true;
}
}
}
}
return false;
}
}
カスタム制約の使用方法は次のとおりです。
routes.MapRoute(
name: "Default2",
url: "{controller}/{action}/{param1}-{param2}",
defaults: new { controller = "Admin", action = "Index" },
constraints: new { lang = new CustomRouteConstraint(new RoutePatternCollection( new List<ParamType> { ParamType.INT, ParamType.INT })) }
);
(私がコンストラクターに渡しているのは、基本的に「検索するパラメーター パターンは 2 つの整数です」と言っています。そのため、Match
メソッドが呼び出されると、url で指定されたアクションに 2 つの整数パラメーターが 2 つある場合は true が返されます。実際のパラメーター名。)
では、このリクエストの RouteValueDictionary を上書きする方法はありますか? または、私が行方不明になっているこれを行うことができる他の方法はありますか?