ASP.NET正在请求路径中对反斜杠进行“规范化”以实现正斜杠,我需要它们以反斜杠的形式通过(用于在数据库中执行查找)。我不介意转义的斜线是否像this question一样未转义地出现。
config.Routes.MapHttpRoute(
name: "TransactionsApi",
routeTemplate: "api/transactions/{*transaction}",
defaults: new { controller = "transactions", transaction = RouteParameter.Optional }
);
请注意,我已设置事务以匹配路径的其余部分。
我尝试了以下URL(均来自浏览器和Fiddler):
api/transactions/mscorlib.pdb\DFA83312EAB84F67BD225058B188F22B1\mscorlib.pdb
api/transactions/mscorlib.pdb\\DFA83312EAB84F67BD225058B188F22B1\\mscorlib.pdb
api/transactions/mscorlib.pdb%5CDFA83312EAB84F67BD225058B188F22B1%5Cmscorlib.pdb
api/transactions/mscorlib.pdb%5C%5CDFA83312EAB84F67BD225058B188F22B1%5C%5Cmscorlib.pdb
当他们使用我的Web API方法时,它们都是
mscorlib.pdb/DFA83312EAB84F67BD225058B188F22B1/mscorlib.pdb
。我检查了当前的HttpContext
,看起来ASP.NET正在执行此规范化(不是MVC4)。可能的解决方案:
{*transaction}
部分(如果包含反斜杠)。并非真正的地址栏可入侵关于如何将ASP.NET转换为而不是的任何想法,请进行标准化吗?
最佳答案
简短答案
您无法阻止此行为,因为它已硬编码到IIS中。
调查
我想通过反编译运行时并遵循代码来调查此问题。这样做总是很高兴的:您了解运行时的工作方式,有时会发现问题。让我们开始旅程...
首先,我将从HttpRuntime类开始使用ILSpy反编译System.Web。浏览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)
最后一种(不安全的)方法正在对路径进行操作。首先,每个字符都有一个循环。如果char低于'。',并且不同于'/'且等于'\',则为
flag = true
。循环之后,if (flag)
(src),然后可能会引发异常,而virtualPath = UrlPath.FixVirtualPathSlashes(virtualPath);
(src)。现在看来,没有任何东西可以帮助我们避免去那里(也许是呕吐物?)。
string FixVirtualPathSlashes(string virtualPath)
(src)将反斜杠替换为斜杠,如果要删除重复的斜杠。耻辱。那
GetEurl
方法呢?当您阅读src时,您会发现这对您没有帮助。结论
http运行时没有任何记载的原因会杀死您的反斜杠。您无法禁用此行为。
解决方法#1
现在,必须有一种方法。引用This guy的this page有一个解决方法。似乎使用重写模块,您可以将原始URL重新放入管道中。我真的不喜欢这种解决方案,因为我不知道到底发生了什么。我还有一个主意
我还没有测试这个东西。你可以吗?
搜索解决方法2(未找到)
如果有一个原始请求路径存储的地方怎么办?
搜索
HttpRequest
,Url.OriginalString
,RawUrl
,Path
和ServerVariables
均不包含所需的值。甚至没有_filePath
,_path
,_queryStringText
,_rawUrl
,_rewrittenUrl
和_url
私有(private)字段。搜索
IIS7WorkerRequest
,该值已在运行时更改。我怀疑IIS在将请求推送到ASP.NET运行时之前就已经做了。似乎没有希望。