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)。

    可能的解决方案:
  • 在插入事务时,将'\'标准化为'/',以便无论ASP.NET通过什么查询都将成功。好像有点臭
  • Base64 {*transaction}部分(如果包含反斜杠)。并非真正的地址栏可入侵

  • 关于如何将ASP.NET转换为而不是的任何想法,请进行标准化吗?

    最佳答案

    简短答案

    您无法阻止此行为,因为它已硬编码到IIS中。

    调查

    我想通过反编译运行时并遵循代码来调查此问题。这样做总是很高兴的:您了解运行时的工作方式,有时会发现问题。让我们开始旅程...

    首先,我将从HttpRuntime类开始使用ILSpy反编译System.Web。浏览public static void ProcessRequest(HttpWorkerRequest wr)ProcessRequestNoDemandProcessRequestNowProcessRequestInternal ...

    在这里,我想调查以下几行: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 guythis page有一个解决方法。似乎使用重写模块,您可以将原始URL重新放入管道中。我真的不喜欢这种解决方案,因为我不知道到底发生了什么。我还有一个主意

    我还没有测试这个东西。你可以吗?

    搜索解决方法2(未找到)

    如果有一个原始请求路径存储的地方怎么办?

    搜索HttpRequestUrl.OriginalStringRawUrlPathServerVariables均不包含所需的值。甚至没有_filePath_path_queryStringText_rawUrl_rewrittenUrl_url私有(private)字段。

    搜索IIS7WorkerRequest,该值已在运行时更改。我怀疑IIS在将请求推送到ASP.NET运行时之前就已经做了。似乎没有希望。

    10-02 01:58