WebRequest
Web アプリケーション (Mono 上の XSP でホスト)で非常に奇妙な問題が発生していますServiceStack
。リクエスト モジュールの登録が非常に奇妙な方法で動作しているようです。を使用してWebRequest
HTTP リクエストを作成していますが、その「プレフィックス」(HTTP) の作成者が見つからないため失敗しています。
私が見ている例外は でNotSupportedException
、HTTPプレフィックスに作成者が登録されていないという事実を追跡することができました(https://github.com/mono/mono/blob/master/mcs/class/System/System.Net/WebRequest.cs(479行目あたり)
編集:詳細:NotSupportedException
は によってスローされますWebRequest.GetCreator
。 は、URL プレフィックスをキーとして使用して、返す作成者を選択します。私の場合は ですHttpRequestCreator
。 この例外は、"HTTP" プレフィックスに登録された作成者がいないためにスローされます (実際には、作成者がまったく存在しません)。
そこで少し調べてみて、Monoのソースを調べてみると、モジュールは(または追加されるべき)webRequestModules
セクションに追加されていることがわかりましたsystem.web
。*.configファイル。
私は自分のマシン.configファイルには次の内容が記載されています:
System.Net.HttpRequestCreator, System, Version=4.0.0.0
見つめているWebRequest Mono ソースプレフィックスは、クラスの静的コンストラクター内の構成から追加されるようです (私見では良い選択ではありませんが、それでも動作するはずです)。
HttpRequestCreator
これをテストするために、に を追加しようとしましたsystem.net/webRequestModules
。web.config
これは XSP/Mono によってロードされ、重複キー例外が発生します ( はHttpRequestCreator
すでにロードされているはずなので、これは予想どおりです。マシン.config)。
さらに奇妙なことに:次のように、Http のモック ハンドラーを追加します。
bool res = System.Net.WebRequest.RegisterPrefix ("http", new MyHttpRequestCreator ());
Debug.Assert (res == false);
アサーションは時々成功しますが、時々失敗します! (RegisterPrefix
同じプレフィックスの作成者がすでに登録されている場合は「false」を返します。常に false を返すことを期待していますが、そうではありません! 繰り返しますが、完全にランダムです)
登録が「失敗」した場合 (つまり、「HTTP」プレフィックスがすでに登録されているため false が返された場合)、 HTTP のリクエストを作成できます。これは、呼び出しが静的コンストラクターを「起動」して実行させるようWebRequest
なものです。RegisterPrefix
私は困惑している: の静的コンストラクタの実行中に競合状態が発生しているように見えますWebRequest
が、これは意味がありません (ランタイムは静的コンストラクタをロックで保護します、IIRC)
何が足りないのでしょうか? この問題を解決するにはどうすればよいでしょうか? これは私の責任 (誤解または見落とし) でしょうか、それとも Mono のバグのように見えるので、提出すべきでしょうか?
詳細:
mono --version
Mono JIT コンパイラ バージョン 3.0.6 (Debian 3.0.6+dfsg-1~exp1~pre1)
おそらく関連しているが、回答されていない質問:
ベストアンサー1
この問題に関しては、次のハッキーな回避策を試してください:
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;
}