我在ServiceStack Web应用程序中有一个非常奇怪的WebRequest问题(由Mono上的XSP托管)。 似乎请求模块的注册以一种非常奇怪的方式工作;我正在使用WebRequest创建HTTP请求,但它失败了,因为它无法找到该“前缀”(HTTP)的创建者。
我看到的例外是NotSupportedException
,我能够跟踪它没有为HTTP前缀注册创建者的事实(我在第479行附近点击https://github.com/mono/mono/blob/master/mcs/class/System/System.Net/WebRequest.cs)
编辑:更多详细信息:NotSupportedException
引发WebRequest.GetCreator
,HttpRequestCreator
使用网址前缀作为键来选择要返回的创建者;就我而言,System.Net.HttpRequestCreator, System, Version=4.0.0.0
。抛出异常是因为没有为“HTTP”前缀注册的创建者(实际上,根本没有创建者)。
所以我搜索了一下,挖掘了Mono源代码,发现模块是(或应该)添加到system.web的webRequestModules部分的各种* .config文件中。
我查看了我的machine.config文件,它是:
HttpRequestCreator
关注WebRequest Mono sources 似乎前缀是从配置中添加的,确实是在类静态构造函数内部(不是一个好的选择,恕我直言,但仍然......应该工作)。
为了测试它,我尝试在system.net/webRequestModules
中添加web.config
到bool res = System.Net.WebRequest.RegisterPrefix ("http", new MyHttpRequestCreator ());
Debug.Assert (res == false);
;这是由XSP / Mono加载并导致重复的键异常(这是预期的,因为HttpRequestCreator应该已经加载,因为它已经存在于machine.config中)。
更奇怪的是:如果我为Http添加一个模拟处理程序,就像这样:
{{1}}
断言有时会过去......有时不会! (如果已经注册了相同前缀的创建者,则RegisterPrefix返回“false”;我希望它总是返回false,但事实并非如此!再次,它是完全随机的)
当注册“失败”(即因为已经注册了“HTTP”前缀而返回false)时,WebRequest可以创建HTTP请求。就像调用RegisterPrefix“唤醒”静态构造函数并让它运行一样。
我很困惑:它似乎是执行WebRequest的静态构造函数时的竞争条件,但这没有意义(运行时保护带有锁的静态构造函数,IIRC)
我错过了什么? 我该如何解决或解决这个问题? 这是我的错(误解或遗漏某些东西)还是看起来像是一个Mono bug,因此我应该提交它吗?
详细说明:
单声道 Mono JIT编译器版本3.0.6(Debian 3.0.6 + dfsg-1~exp1~pre1)(可能相关,未回答的问题:HTTP protocol not supported in WebRequest under mono)