我正在使用IIS 7 Rewrite模块来重写传入的URL,如:
至
http://server/application/controller/year/all
一切正常,除了当处理重写的请求时,我使用MVC的UrlHelper.GenerateUrl()方法:
UrlHelper.GenerateUrl( "Assets","Css","Asset",new RouteValueDictionary(new { site = site.Name,assetPath = assetPath }),RouteTable.Routes,controllerContext.RequestContext,false);
System.Web.HttpException: Cannot use a leading .. to exit above the top directory. at System.Web.Util.UrlPath.ReduceVirtualPath(String path) at System.Web.Util.UrlPath.Reduce(String path) at System.Web.VirtualPath.Combine(VirtualPath relativePath) at System.Web.VirtualPathUtility.Combine(String basePath,String relativePath) at System.Web.Mvc.PathHelpers.GenerateClientUrlInternal(HttpContextBase httpContext,String contentPath) at System.Web.Mvc.PathHelpers.GenerateClientUrl(HttpContextBase httpContext,String contentPath) at System.Web.Mvc.UrlHelper.GenerateUrl(String routeName,String actionName,String controllerName,RouteValueDictionary routeValues,RouteCollection routeCollection,RequestContext requestContext,Boolean includeImplicitMvcValues)
看到RequestContext,似乎所有的请求路径都是正确的(即重写的值).我似乎无法弄清楚为什么它试图退出顶级目录…在路径中没有任何地方使用….
我还确保RewriteModule位于IIS中的UrlRouting模块之上.
虽然我可以进入框架方法,但我无法检查任何本地变量(在VS或WinDbg中),因为它已被编译器优化.
有什么想法吗?
解决方法
这是一个怪诞的解决方法,涉及私有实现细节,但添加一下:
HttpContext.Current.Request.ServerVariables.Remove("IIS_WasUrlRewritten");
这样可以避免在PathHelper.GenerateClientUrlInternal中进行内部检查,以查看请求是否被重写.这很可能会打破一些场景,正如参考资料中的这个评论所暗示的那样:
// Since the rawUrl represents what the user sees in his browser,it is what we want to use as the base // of our absolute paths. For example,consider mysite.example.com/foo,which is internally // rewritten to content.example.com/mysite/foo. When we want to generate a link to ~/bar,we want to // base it from / instead of /foo,otherwise the user ends up seeing mysite.example.com/foo/bar,// which is incorrect.