简短回答
你无法阻止这种行为,因为它已经被编码到IIS中。
调查
我想通过反编译运行时并跟踪代码来调查这个问题。这样做总是有好处的:你可以了解运行时的工作方式,有时候你还能找到问题所在。让我们开始这段旅程...
作为起点,我使用ILSpy反编译System.Web,从HttpRuntime类开始。通过 public static void ProcessRequest(HttpWorkerRequest wr)
、ProcessRequestNoDemand
、ProcessRequestNow
、ProcessRequestInternal
...进行导航。
在这里,我想调查以下几行:
httpContext = new HttpContext(wr, false);
,
httpContext.Response.InitResponseWriter();
,
httpAsyncHandler.BeginProcessRequest(httpContext, this._handlerCompletionCallback, httpContext);
.
在 HttpContext.HttpContext(HttpWorkerRequest wr, bool initResponseWriter)
中,许多事情可能会导致这种情况:
this.Init(request, response)
,
new HttpRequest(wr, this)
。
更准确地说,HttpContext.GetEurl()
(看起来可疑),
Request.InternalRewritePath(VirtualPath.Create(virtualPath), null, true)
(安全),
VirtualPath.Create(virtualPath)
(看起来非常可疑),
virtualPath = UrlPath.FixVirtualPathSlashes(virtualPath);
(臭名昭著!)。
让我们编写导致此处的堆栈跟踪:
HttpRuntime.ProcessRequest...
(多个方法)
new HttpContext(wr, false)
this.Init(new HttpRequest(wr, this), new HttpResponse(wr, this));
if (!string.IsNullOrEmpty(eurl))
(我们可以防止进入 if 吗?)
this.Request.InternalRewritePath(VirtualPath.Create(virtualPath), null, true);
VirtualPath Create(string virtualPath)
unsafe static VirtualPath Create(string virtualPath, VirtualPathOptions options)
这个(不安全的)最后一种方法正在对路径进行某些操作。首先,循环遍历每个字符。如果一个字符在“.”以下,并且与“/”不同且等于“\”,那么
flag = true
。循环结束后,
if (flag)
(
src),则可能会抛出异常,并且
virtualPath = UrlPath.FixVirtualPathSlashes(virtualPath);
(
src)。
目前似乎没有什么能帮助我们避免去那里(也许是eurl的事情?)。
string FixVirtualPathSlashes(string virtualPath)
(
src)将反斜杠替换为斜杠,并删除重复的斜杠。可惜了。
关于GetEurl
方法呢?当你阅读src时,你会发现它对你没有帮助。
结论
HTTP运行时因没有文档记录的原因而删除了你的反斜杠。没有办法可以禁用此行为。
解决方法 #1
现在,一定有办法。这个人参考这个页面有一个解决方法。似乎使用重写模块,你可以将原始URL放回管道中。我不是很喜欢这个解决方案,因为我不知道到底发生了什么。我有另一个想法...
我还没有测试过这个东西。你能吗?
搜索解决方法 #2(未找到)
如果有一个地方存储了原始请求路径会怎样呢?
搜索HttpRequest
,但是Url.OriginalString
、RawUrl
、Path
、ServerVariables
中都没有所需的值。甚至私有字段_filePath
、_path
、_queryStringText
、_rawUrl
、_rewrittenUrl
、_url
也没有。
在IIS7WorkerRequest
中搜索,该值已经在运行时更改。我怀疑IIS在将请求推送到ASP.NET运行时之前就完成了这个操作。看起来没有希望了。