作爲this question的後續,我試圖實現自定義路由約束,以動態修改特定路由的RouteValueDictionary
。動態修改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
方法被調用,它將如果動作返回true。在url中指定有兩個兩個整數參數,無論o f實際參數名稱。)
那麼,有沒有一種方法可以覆蓋RouteValueDictionary的這個請求?或者有沒有其他方法可以做到這一點,我錯過了?
不是ASP的專家。NET MVC,但我不知道路由字典是否是共享資源,無論是C#中的static或VB.NET中的Shared?如果是這樣,那麼當您修改它時,您可能需要使用鎖定,因爲其他請求可能會在您更改它的同時嘗試讀取它。 –