2

次のようなWebサービスがあります。

[ServiceContract]
public class MyService
{
   [OperationContract]
   public void BreakStuff()
   {
      throw new MyException();
   }
}

今のところそれほど強力なWebサービスではありませんが、ご覧ください。すばらしいものになるでしょう。

を呼び出すと、WCFは例外をトラップし、HTTP 500を返し、 trueに設定されているBreakStuff()場合は、オプションでシリアル化されたスタックトレースを吐き出します。IncludeExceptionDetailsInFaultsこの動作をオーバーライドして、独自のカスタムエラーメッセージオブジェクトを吐き出し、HTTP 200を返したいと思います。特定の場合に例外をスローする方が、コードをtry / catchブロックで散らかしてすべてを処理するよりもクリーンだと思うので、これを実行したいと思います。 Webメソッドは、ある種のResultオブジェクトを返します。

私がやったことIDispatchMessageFormatterは、契約を結んでいる自分自身で実装されています。

public interface IDispatchMessageFormatter
{
   void DeserializeRequest(Message message, object[] parameters);
   Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result);
}

SerializeReplyは通常のHTTP200応答に対して呼び出されますが、Webメソッドが例外をスローした場合、WCFは呼び出さSerializeReplyれないため、応答出力を制御する機会が与えられません。

WCFはエラー応答をカスタマイズする機能を提供しますか?

4

1 に答える 1

2

IErrorHandlerインターフェイスを実装することにより、カスタム エラー ハンドラを実装できます。過去にこのアプローチを使用して、JSON 形式でカスタム エラー情報を返しました。ProvideFaultメソッドでは、応答コードを変更することもできます。以下は、私が使用した 1 つのアプローチのサンプルです。

public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{   
    fault = GetJsonResponseFromException(version, error);
    ConfigureMessageFormat(ref fault);
    ConfigureHttpReponse(ref fault, error);
}

protected virtual void ConfigureMessageFormat(ref Message fault)
{
    var formatting =
      new WebBodyFormatMessageProperty(WebContentFormat.Json);
    fault.Properties.Add(WebBodyFormatMessageProperty.Name, formatting);
}

protected virtual void ConfigureHttpReponse(ref Message fault, Exception error)
{
    var exception = error as WebFaultException<ServiceFault>;
    var statusCode = HttpStatusCode.InternalServerError;
    var description = HttpWorkerRequest
        .GetStatusDescription(Convert.ToInt32(statusCode));

    if (exception != null)
    {
        statusCode = exception.StatusCode;
        description = exception.Reason.Translations[0].Text;
    }

    var httpResponse = new HttpResponseMessageProperty()
    {
        StatusCode = statusCode,
        StatusDescription = description
    };

    httpResponse.Headers[HttpResponseHeader.ContentType] = "application/json";
    fault.Properties.Add(HttpResponseMessageProperty.Name, httpResponse);
}
于 2012-11-29T05:08:23.373 に答える