WCF REST Starter Kit Preview の Sample である WebException, WebException2 には、WebProtocolExceptionを使用して例外を処理する方法が説明されています。
WebException は Preview版に含まれる WebErrorHandler ないで処理されることにより、例外の発生したオペレーションのレスポンスフォーマット (WebInvokeAttribute や WebGetAttribute の WebMessageFormat の値)に従って適切な形式(xml,json)でエラーメッセージをブラウザのレスポンスに設定されるようにしています。
WebException2 はPreview版に含まれる WebErrorHandlerのEnableAspNetCustomErrors を true にすることにより、 WebProtocolException 例外を、ASP.NET の例外処理に統合する方法を説明しています。WebException2では発生した例外をGlobal.asax.csのApplication_EndRequest で例外を補足しています。
- 動作環境:IIS6.0 on Windows Server 2003
- 実装確認: Visaul Studio 2008 Professional
- .NET 3.5 SP1, WCF REST Starter Kit Preview版
1. WebProtocolException
WebExceptionのサンプルは非常にシンプルです。Service.svc.csの抜粋を掲載します。
[ServiceBehavior(IncludeExceptionDetailInFaults = true, InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)] [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] [ServiceContract] public partial class Service {
.... [WebInvoke(UriTemplate = "DoWork")] [WebHelp(Comment = "This method returns HTTP status code Conflict with a custom XML body")] [OperationContract] SampleResponseBody DoWork(SampleRequestBody request) { throw new WebProtocolException(HttpStatusCode.Conflict, "Custom error data", new SampleErrorBody() { Error = "Sample error" }, null); } [WebInvoke(UriTemplate = "DoWork?json", ResponseFormat = WebMessageFormat.Json)] [WebHelp(Comment="This method returns a HTTP status code Conflict with a custom json error body")] [OperationContract] SampleResponseBody DoWorkJson(SampleRequestBody request) { throw new WebProtocolException(HttpStatusCode.Conflict, "Custom error data in json", new SampleErrorBody() { Error = "Sample error in json" }, null); } }
DoWork オペレーションでは WebInvoke の ResponseFormat が指定されていないので、例外が発した場合は、XML形式でエラーメッセージが返されます。DoWorkJsonは WebInvoke の ResponseFormat が Json のため、Json形式で例外の詳細が返されます。Service には、ほかにもGetData というWebGetAttribute でアノテートされたオペレーションもあります。このメソッドはResponseFormat を指定されていないので、xml形式でエラーメッセージが返されますが、実際はxhtmlのメッセージを返しています。WebProtocolException のどのコンストラクタを使用するかで変わります。詳細は、Preview版の WebProtoclException.cs 内のDataContractDetailWriter クラスと、StringDetailWriter クラスの定義と、コンストラクタでとちらが選択されるかを確認してください。
WebException2では、ASP.NET の例外機構に統合するサンプルです。これは WebException2 サンプルの Service.svc 内で、WebServiceHost2 の EnableAspNetCustomErrors を true にする(結果的にWebErrorHandler.EnableAspNetCustomErrorsがtrueになる)ことで統合できるようにしています。
例外の処理を行っているGlobal.asax.csの抜粋は次のようになっています。サンプルではエラーページにリダイレクトしています。
protected void Application_EndRequest(object sender, EventArgs e) { if (HttpContext.Current.Error != null) { WebProtocolException webEx = HttpContext.Current.Error as WebProtocolException; if (webEx != null && webEx.StatusCode == HttpStatusCode.BadRequest) { HttpContext.Current.ClearError(); HttpContext.Current.Response.Redirect("BadRequest.htm"); } } }
2.おまけ
説明は以上です。最後に、こりずに readme.txt を翻訳します。以下はWebExceptionのreadme.txtです。
本サンプルではREST例外に対する例外プログラミングモデルのサポートを説明しています。オペレーションに指定された出力フォーマット(xml もしくは json ) に応じてレスポンセうが返されます。エラーメッセージはシンプルな文字列かもしくはシリアライズ可能なCRL型です。
次にWebException2のreadme.txtの翻訳です。
本サンプルは、WCFのエラー処理機構とASP.NETのカスタム例外機能を統合を説明しています。このサンプルでは、コードはglobal.asaxに追加されており、BadRequst HTTP ステータスコードの場合にカスタムエラーページを表示します。
本サンプルを動かす方法
=====================
ブラウザから、<hostname>/service.svc/GetData?param1=-1 と入力します。param1が負数のため、カスタムエラーページが表示されます。
さんのコメント: さんのコメント: