当 WebRequest 无法找到该前缀的创建者时,发生“ NotSupportedException”

我在 ServiceStack Web 应用程序(由 Mono 上的 XSP 托管)中遇到了一个非常奇怪的 WebRequest问题。 请求模块的注册似乎以一种非常奇怪的方式工作; 我正在使用 WebRequest创建一个 HTTP 请求,但是它失败了,因为它无法找到该“前缀”(HTTP)的创建者。

我看到的例外是 NotSupportedException,我能够跟踪到这样一个事实,即没有创建者注册了 HTTP 前缀(我正在按 https://github.com/mono/mono/blob/master/mcs/class/System/System.Net/WebRequest.cs,在第479行左右)

编辑: 更多细节: NotSupportedExceptionWebRequest.GetCreator抛出,它使用 URL 前缀作为键来选择要返回的创建者; 在我的例子中,是 HttpRequestCreator。之所以引发异常,是因为没有为“ HTTP”前缀注册的创建者(实际上,根本没有创建者)。

因此,我搜索了一下 Mono 源代码,发现模块被(或者应该)添加到 system.webwebRequestModules部分中的一个 * . config文件中。

我看了我的 Machine.config文件,就是这个:

System.Net.HttpRequestCreator, System, Version=4.0.0.0

查看 < a href = “ https://github.com/Mono/Mono/blob/master/mcs/class/System/System.Net/网址1”rel = “ noReferrer”> WebRequest Mono 源代码 前缀似乎是从类静态构造函数内部的配置中添加的(恕我直言,这不是一个好的选择,但仍然是一个好的选择)。.它应该可以工作)。

为了测试它,我尝试在我的 web.config中向 system.net/webRequestModules添加一个 HttpRequestCreator; 这是由 XSP/Mono 加载的,并导致一个重复的键异常(这是预期的,因为 HttpRequestCreator应该已经加载了,因为它已经出现在 Machine.config中)。

更奇怪的是: 如果我为 Http 添加一个模拟处理程序,像这样:

bool res = System.Net.WebRequest.RegisterPrefix ("http", new MyHttpRequestCreator ());
Debug.Assert (res == false);

断言有时会过去... 有时不会! (如果相同前缀的创建者已经注册,则 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)

可能是相关的,没有答案的问题:

2845 次浏览

在这个问题上尝试一下这种变通方法:

private static HttpWebRequest CreateWebRequest(Uri uri)
{
var type = Type.GetType("System.Net.HttpRequestCreator, System, Version=4.0.0.0,Culture=neutral, PublicKeyToken=b77a5c561934e089");
var creator = Activator.CreateInstance(type,nonPublic:true) as IWebRequestCreate;
return creator.Create(uri) as HttpWebRequest;
}