我正在升级我们的应用程序,它有一个内部web服务器,从。net 2.0到。net 4.0。
我正在处理一个对象HttpListenerWorkerRequest
的请求,它扩展了HttpWorkerRequest
类,并创建了一个请求,其中GetRawUrl()
返回http://localhost:82/Default.aspx
格式的Url。
在。net 2.0中,将此发送到HttpRuntime.ProcessRequest(httpListenerWorkerRequest)
没有问题,但是在。net 4.0中,我得到一个网页,上面只有文本"错误请求"。
打开HttpRuntime
,我可以看到从ProcessRequestInternal(HttpWorkerRequest wr)
抛出的错误请求,这是一个试图构建HttpContext的私有方法。
我自己试过了:
try
{
//what's going on?
hcontext = new HttpContext(workerRequest);
}
catch(Exception e)
{
//Debugging break point here
}
Pre-update(。. NET 2.0),它构建良好,更新后(。. NET 4.0),我得到了一个系统。ArgumentException声明
The relative virtual path 'http:/localhost:82/Default.aspx' is not allowed here
,抛出
at System.Web.VirtualPath.Create(String virtualPath, VirtualPathOptions options)
at System.Web.HttpRequest.get_ClientFilePath()
at System.Web.Security.CookielessHelperClass.RemoveCookielessValuesFromPath()
at System.Web.HttpContext.Init(HttpRequest request, HttpResponse response)
at System.Web.HttpContext..ctor(HttpWorkerRequest wr)
at Talcasoft.Web.Hosting.HttpWorkerThread.Run(Object request) in
C:[OurLibrary].WebHostingHttpWorkerThread.cs:line 51
.NET中发生了什么变化导致了这个问题,我能做些什么来解决这个问题?
EDIT我刚刚注意到,不允许的http:后面跟着一个斜杠,而不是双精度,尽管请求中的GetRawUrl()肯定返回双精度。
我不是100%确定这是"确切的答案",但看起来很接近我-还有一些要写…
似乎在VirtualPath
类中有一种breaking change
-并且它证实了他们如何检查illegal characters
。(顺便说一句。你可以谷歌一下"VirtualPath源代码",它似乎是。net 4版本)。
在VirtualPath.Create
内部调用了一个检查'非法虚拟路径字符'。
它首先进入注册表("HKEY_LOCAL_MACHINESOFTWAREMicrosoftASP")。. NET", "VerificationCompatibility") -查看是否应该使用compatibility
模式的'非法字符'。
基于此,我猜(我没有办法检查这个)如果您将上述注册表值(int)设置为
所示。1
-,则你应该让你的方法工作the old way
和w/o任何额外的努力。注意:可能需要重新启动IIS(或主机进程),如其中一个链接
然后根据注册表标志,它使用了这两个…
':', '?', '*', ' ' // .NET 4.0 - the default
' ' // the 'compatibility' mode
这似乎很好地描述了你的故事,因为你的路径与'port'指定实际上是illegal
。
最终编辑/解释:
(基于注释和解决方案更新)
这是我对里面发生的事情的理解:
1) . net 4.0之前的解决方案是VerificationCompatibility
密钥(见上文)。
VirtualPath.Create
之前,所有路径都是固定和规范化的-并且您的http://...
成为预期的绝对路径/Default.aspx
。然而,当您提供HttpWorkerRequest
(而不是请求/响应等)时,raw Url
直接从worker
- 中获取,并且提供正确和规范化路径的责任取决于您的工作请求。(这仍然有点不确定,看起来像是一个错误或内部处理不当)。
重现问题:
internal class MyRequest : SimpleWorkerRequest
{
public MyRequest() : base("", "", String.Empty, String.Empty, null) { }
public override String GetRawUrl() { return "http://localhost:82/Default.aspx"; }
}
// ...
var wr = new MyRequest();
var context1 = new HttpContext(wr);
给出错误The relative virtual path 'http:/localhost:82/Default.aspx' is not allowed here.
修复:
public override String GetRawUrl()
{ return new Uri(url, UriKind.RelativeOrAbsolute).AbsolutePath; }
一些关于这个主题的研究基于注册表中的
VerificationCompatibility
关键字这似乎是它的关键。URL文件名=错误请求
配置IIS接受带有特殊字符的URL
在注册表
这是一个类似的东西从微软-但似乎是一个'hotfix'的'2.0',也就是说,并不适用于你-但只是附加它作为官方的东西在这一行。
修复。net Framework 1.1中的"HTTP 400 - Bad request"错误信息
修复:当你试图访问ASP时出现错误信息。基于。NET 2.0的Web页面:"HttpException (0x80004005): '/HandlerTest/WebForm1. "Aspx/a:b'不是有效的虚拟路径"
ASP。. NET 2.0 x64 -您可能会收到KB 932552或826437中提到的HTTP 400错误请求或错误
HKEY_LOCAL_MACHINE 微软软件 ASP。净
DWord值名称:VerificationCompatibility值数据:1
以下是我的看法。它仍然包含一些猜测,但我将包括一个测试,你可以证明或反驳这个假设。
堆栈跟踪显示ClientFilePath.get
是异常的起源。它看起来像这样:
if (this._clientFilePath == null)
{
string rawUrl = this.RawUrl;
int index = rawUrl.IndexOf('?');
if (index > -1)
{
rawUrl = rawUrl.Substring(0, index);
}
this._clientFilePath
= VirtualPath.Create(rawUrl, VirtualPathOptions.AllowAbsolutePath); //here!
}
return this._clientFilePath;
它创建一个VirtualPath
并且只允许绝对值。http://localhost:82/Default.aspx
是一个相对路径,因为它不以斜杠开头。在这个上下文中,不是 URL,因为它没有被这样解释。
因此VirtualPath.Create
可以理解地拒绝这条路径。我不知道为什么。net 2.0允许这样做,但是。net 4.0需要一个绝对路径,根据代码,这是不可配置的。
实际上,我以前从未见过HttpRequest.RawUrl
返回URL。根据我的经验,它应该返回一个绝对路径,如/Default.aspx
。如果你想设置主机和端口,你必须找到其他方法。
所以修复是不使用http://localhost:82/Default.aspx
,但/Default.aspx
。这样行吗?