作为对此问题的跟进,我正在尝试实现自定义路由约束,以动态修改特定路由的
我已经完成了95%的工作:根据提供的参数模式匹配url中指定的操作,可以匹配任何路由。这个过程的最后一步是覆盖RouteValueDictionary,将键重命名为控制器操作的适当参数。
以下是我的代码相关片段(整个类几乎有300行,因此我不想添加全部内容,但如果需要,我可以添加):
我传递给构造函数的基本上是在说“要查找的参数模式是两个整数”。所以当调用
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 })) }
);
我传递给构造函数的基本上是在说“要查找的参数模式是两个整数”。所以当调用
Match
方法时,如果url中指定的操作具有两个整数参数(而不管实际参数名称),它将返回true。
因此,我能否覆盖此请求的RouteValueDictionary?还是我错过了其他方法可以做到这一点?
static
还是VB.NET中的Shared
?如果是这样的话,那么当您修改它时,其他请求可能正在尝试同时读取它,因此您需要使用锁定。 - John Saunders