2

注: .NET 2.0 および VS2005 を IDE として使用する

皆さんこんにちは、

私はデータベースへの Web サービス呼び出しのログ記録に取り組んでおり、最終的に、別のプロジェクトから移植された非常に簡素化された実装を使用して SoapExtension を構成し、実行することができました。すべてのメソッドで実行されるように、構成ファイルで設定しました。Web サービスを呼び出して SOAP 拡張機能が起動すると、SoapServerMessage がその MethodInfo プロパティを呼び出そうとすると、NullPointerException がスローされます。

System.Web.Services.Protocols.SoapException: There was an exception running the extensions specified in the config file. 
---> System.NullReferenceException: Object reference not set to an instance of an object.
at System.Web.Services.Protocols.SoapServerProtocol.get_MethodInfo()
at System.Web.Services.Protocols.SoapServerMessage.get_MethodInfo()
at MyService.SOAPLoggingExtension.LogInput(SoapMessage message)
at MyService.SOAPLoggingExtension.ProcessMessage(SoapMessage message) 
at System.Web.Services.Protocols.SoapMessage.RunExtensions(SoapExtension[] extensions, Boolean throwOnException)
at System.Web.Services.Protocols.SoapServerProtocol.Initialize()
--- End of inner exception stack trace ---
at System.Web.Services.Protocols.SoapServerProtocol.Initialize()
at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing)

LogInput メソッドは、ProcessMessage(SoapMessage) の BeforeDeserialize ステージで呼び出されます。

SoapMessageStage.BeforeDeserialize:
   CopyStream(_oldStream, _newStream);
   _newStream.Position = 0;

   if(_enabled)
      LogInput(message);
   break;

また、ログに記録しようとしているメッセージ オブジェクトの MethodInfo プロパティにアクセスしようとすると、LogInput メソッドが失敗します。プロパティが呼び出されるコードのブロックは次のとおりです。

entry = new MyServerLogEntry();
entry.ServerURL = message.Url;
entry.Method = (message.MethodInfo == null) ? null : message.MethodInfo.Name;

message.MethodInfo が呼び出されると、SoapServerProtocol.get_MethodInfo() にバブル オーバーし、そこで null 参照例外がスローされます。私はググって、Stack Overflow でこのあたりをチェックしましたが、MethodInfo プロパティが例外をスローする理由を見つけることができませんでした。

Web サービスの呼び出し中にこの MethodInfo プロパティが適切に初期化されるようにする方法を知っている人はいますか?

追加の詳細: MethodInfo プロパティにアクセスしようとしない場合、拡張機能は正しく機能し、データベースにログが記録されます。

4

2 に答える 2

2

試行錯誤の末、この問題を解決することができました。理由は完全にはわかりませんが、SoapMessage オブジェクトは BeforeDeserialize 段階で完全に初期化されていません。Action プロパティと MethodInfo プロパティの両方が、この段階でエラーをスローします。

ただし、AfterSerialize 段階では、これらのオブジェクトは適切に初期化されているように見えます。メッセージ名を読み取る行を後の段階に移動することで、例外をスローすることなく、ログ エントリ オブジェクトを適切に埋めることができます。

正しい順序は次のとおりです。

  1. デシリアライズ前

    を。サーバー URL の読み取り

    b. 要求情報を取得する (証明書、ユーザー ホスト アドレスなど)

    c. ストリームからリクエストの内容を読み取る

  2. AfterSerialize

    を。読み取り例外

    b. MethodInfo 情報 (および必要に応じて Action 情報) を読み取る

    c. ストリームからの応答コンテンツの読み取り

于 2008-10-22T17:36:07.177 に答える
1

MSDN によると、メソッド情報は AfterDeserialization と BeforeSerialization の間のみ利用可能です。それが問題の一部になります。

于 2008-10-22T17:54:08.747 に答える