私の最近のプロジェクト (WCF REST サービス) では、WebServiceHostFactoryを使用していますが、 IErrorHandlerを使用してこれを達成することができました。以下のサンプルを探す
シリアル化してクライアントに送り返すクラス ExceptionInfo を作成しました。
[Serializable]
public class ExceptionInfo
{
public string ExceptionType { get; set; }
public string ExceptionMessage { get; set; }
public string StackTrace { get; set; }
}
カスタム エラー ハンドラの実装
[DataContract]
public class MyCustomServiceErrorHandler : IErrorHandler
{
#region IErrorHandler Members
/// <summary>
/// This method will execute whenever an exception occurs in WCF method execution
/// </summary>
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
var exceptionInfo = new ExceptionInfo();
if (error is MyCustomException)
exceptionInfo.ExceptionType = error.Type.ToString();;
else
exceptionInfo.Type = "Unhandled Exception";
exceptionInfo.ExceptionMessage = error.Message;
exceptionInfo.StackTrace = error.StackTrace;
var faultException = new FaultException<ExceptionInfo>(exceptionInfo);
object detail = faultException.GetType().GetProperty("Detail").GetGetMethod().Invoke(faultException, null);
fault = Message.CreateMessage(version, "", detail, new DataContractSerializer(detail.GetType()));
var webBodyFormatMessageProp = new WebBodyFormatMessageProperty(WebContentFormat.Xml);
fault.Properties.Add(WebBodyFormatMessageProperty.Name, webBodyFormatMessageProp);
var httpResponseMessageProp = new HttpResponseMessageProperty();
httpResponseMessageProp.Headers[HttpResponseHeader.ContentType] = "application/xml";
httpResponseMessageProp.StatusCode = HttpStatusCode.BadRequest;
httpResponseMessageProp.StatusDescription = exceptionInfo.ExceptionMessage;
fault.Properties.Add(HttpResponseMessageProperty.Name, httpResponseMessageProp);
}
/// <summary>
/// Performs error related behavior
/// </summary>
/// <param name="error">Exception raised by the program</param>
/// <returns></returns>
public bool HandleError(Exception error)
{
// Returning true indicates that an action(behavior) has been taken (in ProvideFault method) on the exception thrown.
return true;
}
これで、上記のハンドラーを使用してサービスを装飾できます。
[ServiceContract]
[ServiceErrorBehavior(typeof (MyCustomServiceErrorHandler))]
public class LoginService : ServiceBase
{}
クライアント側では、応答の HttpStatusCode が != Ok かどうかを確認し、応答を ExceptionInfo タイプにデシリアライズして、要件ごとにメッセージ ボックスまたはハンドルに表示できます。
お役に立てれば。