はじめに
SOAPとは、XMLで構成されたメッセージを、HTTPなどのプロトコルで送受信するための仕組みです。メッセージは送信する際にXML形式にシリアライズされ、受信する際には逆シリアライズされます。正常時はもちろん例外発生時にも同様にXML形式で情報が返されます。
SOAPの仕様によると例外発生時には、このXML形式に定義されるdetail
要素に任意の情報を付加するように定められています。しかし、特別な仕組みを構築せず、Webサービスを作成した状態で例外が発生しても、detail
要素には何の情報も設定されません。取得できる情報はmessage
要素に含まれるExceptionのメッセージとスタックトレース程度です。
そこで本稿では、.NET Frameworkで提供されるSOAP機能拡張を使い、Webサービス内で発生した例外を一元的にハンドリングし、detail
要素に例外情報を付加するSoapExtension
クラスの作成方法について説明します。
detail要素の設定方法
まず、例外発生時のSOAPメッセージにdetail
要素を設定するには、どのような方策が考えられるでしょうか?
- 発生した例外を補足する度にSoapExceptionを生成し、プロパティに情報を設定する。
- プロパティに値が設定されるような例外クラスを独自に作成し、
SoapException
クラスを継承させる。
上記1の場合は、例外が発生する箇所に付加情報を設定するコーディングを都度行わなくてはなりませんし、上記2の場合は付加情報を設定する箇所を一元化できても、NullReferenceException
など実行時に発生するすべての例外をカバーすることはできません。そこでこれらの問題を解決するために、SOAP機能拡張を活用します。
SOAP拡張機能とは?
SOAP拡張機能とは、メッセージ処理の特定の段階でメッセージの検査や変更処理を行うことができる拡張用のアーキテクチャです。実際のコーディングではSoapExtension
クラス、SoapExtensionAttribute
クラスをそれぞれを継承したクラスを作成し、任意のメソッドに属性を付与することで、Webサービスメソッド本体に手を加えることなく、SOAP拡張機能の仕組みを利用することができます。
サンプルプログラムの説明
サンプルは、Webサービスとクライアントプログラムに分かれています。Webサービスの作成手順について、ここでは説明しません。詳しくは、『XML Web サービスの作成とアクセスに関するチュートリアル』(MSDNライブラリ)を参照してください。
Webサービス
サンプルのWebサービスとして、引数として文字列を受け取り、生成したメッセージを返すGenerateMessage
メソッドを実装したMessageService
クラスを作成しました。このメソッドは引数の文字列が空であった場合、例外を返します。GenerateMessage
メソッドにはWebサービスとして公開するため<WebMethod>
属性を付与しています。
Imports System.Web Imports System.Web.Services Imports System.Web.Services.Protocols Public Class MessageService Inherits System.Web.Services.WebService <WebMethod()> _ Public Function GenerateMessage(ByVal str As String) As String If String.IsNullOrEmpty(str) Then Throw New ArgumentException("空の文字は無効です。") End If Return "Hello !" + str End Function End Class
<WebService>
属性、<WebServiceBinding>
属性は省略しています。省略した場合、これらの属性によって設定できる値にはデフォルト値が設定されます。クライアントプログラム
クライアントプログラムとして「SampleForm」クラスを作成しました。SampleFormには文字列を入力するテキストボックスと、生成されたメッセージを表示するテキストボックス、[表示]ボタンを配置しています。[表示]ボタンクリック時にWebサービスのGenerateMessage
関数でメッセージを取得し、表示しています。またSoapException発生時にはmessage
プロパティから情報を取得し、ダイアログ表示しています。
Imports Microsoft.VisualBasic Imports System.Web.Services.Protocols Public Class SampleForm Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click Dim service As MessageProxy.MessageService = _ New MessageProxy.MessageService Try TextBox2.Text = service.GenerateMessage(TextBox1.Text) Catch ex As SoapException MessageBox.Show(ex.message, "エラー情報") End Try End Sub End Class
実行例
正常実行時の画面は次のようになります。
このときのSOAP通信内容をトレースしてみると、次のようになります。
引数を空にし、例外を発生させた場合、次のようなダイアログが表示されます。
このときのSOAP通信内容をトレースしてみると、次のようになります。
この状態ではエラーの内容が分かりづらい上に、必要な情報を取得することもできません。それでは、SOAP機能拡張を利用して例外情報を付加してみましょう。