LockRecursionException 从 .Net 4 中的另一个路由的 GetVirtualData 调用 Route.GetVirtualPath
我在 ASP.Net MVC 2 应用程序中最后定义了一个路由,它将不再使用的旧 url 映射到要重定向到的相应新 url。该路由返回负责实际执行重定向的操作和控制器,并且还返回控制器操作的 url,这是要重定向到的 url。由于路由负责生成要重定向到的新 url,因此它会调用路由器来获取适当的 url。这在 .Net 3.5 上运行得很好,但是当我升级到 .Net 4 时,GetVirtualPath 方法会抛出 System.Threading.LockRecursionException:“此模式下不允许递归读取锁定获取。”。以下代码解决了该问题,但非常难看:
public static string GetActionUrl(HttpContextBase context, string routeName, object routeValues)
{
RequestContext requestContext = new RequestContext(context, new RouteData());
VirtualPathData vp = null;
try
{
vp = _Routes.GetVirtualPath(requestContext, routeName, new RouteValueDictionary(routeValues));
}
catch (System.Threading.LockRecursionException)
{
var tmpRoutes = new RouteCollection();
Router.RegisterRoutes(tmpRoutes);
vp = tmpRoutes.GetVirtualPath(requestContext, routeName, new RouteValueDictionary(routeValues));
}
if (vp == null)
throw new Exception(String.Format("Could not find named route {0}", routeName));
return vp.VirtualPath;
}
有人知道 .Net 4 中的哪些更改可能导致此错误吗?另外,从另一条路线的 GetRouteData 方法调用一条路线是否只是不好的做法,我根本不应该这样做?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
正如您所了解的,不支持从全局路由表中的另一个路由中调用全局路由表中的路由。
全局路由表是一个线程安全的集合,可启用多个读取器或单个路由器。不幸的是,即使在 .NET 3.5 中,您所拥有的代码也从未受到支持,尽管在某些情况下它可能会碰巧起作用。
作为一般说明,路线应该相互独立地运行,所以我不确定您的情况是什么。
As you figured out, it is not supported to call a route in the global route table from within another route in the global route table.
The global route table is a thread-safe collection to enable multiple readers or a single router. Unfortunately the code you have was never supported, even in .NET 3.5, though in some scenarios it may have coincidentally worked.
As a general note, routes should function independent of one another, so I'm not sure what your scenario is here.
v3.5 RouteCollection 使用以下代码:
v4.0 RouteCollection 使用以下代码:
GetRouteData(HttpContextBase httpContext) 在两个版本中都使用以下代码:
GetVirtualPath 使用相同的逻辑。
v4.0 中使用的 ReaderWriterLock 默认情况下不允许递归读锁,这就是发生错误的原因。
将路由复制到新的 RouteCollection 进行第二次查询,或者通过反射更改 ReaderWriterLock 模式。
v3.5 RouteCollection uses the following code:
v4.0 RouteCollection uses the following code:
GetRouteData(HttpContextBase httpContext) in both versions use the following code:
GetVirtualPath uses the same logic.
The ReaderWriterLock used in v4.0 does not allow Recursive read locks by default which is why the error is occurring.
Copy routes to a new RouteCollection for second query, or change the ReaderWriterLock mode by reflecting in.