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