3

Java クライアントと c# mvc3 クライアントによって消費される WCF 4 Rest サービスがあります。レスポンス コンテンツは json として返される必要があります。

一貫した方法で例外/障害をクライアントに返すことができるようにしたいと考えています。WebFaultException を使用する必要があることを読みましたが、実際には正常に動作します。

ただし、Web プロジェクト以外で使用される可能性があるため、アプリケーション ロジック プロジェクトを WebFaultExceptions で汚染したくありません。

そこで、WCF Rest サービスに IErrorHandler を実装してすべての例外をキャッチし、特定の例外、つまり ValidationException については、例外を WebFaultException にラップされたエラーとして返すことを検討しました。ただし、これは機能していないようで、フォーム フィドラーを呼び出すと、次の Http 504 応答が返されます。

[Fiddler] ReadResponse() が失敗しました: サーバーはこの要求に対する応答を返しませんでした。

私がやっていることの本質を示すために、コードを必要最小限に減らしました。

public void ProvideFault(Exception error, 
                         MessageVersion version, 
                         ref Message fault)
{
    var ex = new WebFaultException<Exception>(
                                      new Exception("you can't do that"), 
                                      HttpStatusCode.Unauthorized);

    var xmf = ex.CreateMessageFault();
    fault = Message.CreateMessage(version,
                                  null,
                                  xmf,
                                 new DataContractJsonSerializer(xmf.GetType()));
}

私は何を間違っていますか?

4

1 に答える 1

2

これはCarlosのブログからのサンプルコードです。それは過去に私を助けます。

public class ValidationAwareErrorHandler : IErrorHandler
{
    IErrorHandler originalErrorHandler;
    public ValidationAwareErrorHandler(IErrorHandler originalErrorHandler)
    {
        this.originalErrorHandler = originalErrorHandler;
    }

    public bool HandleError(Exception error)
    {
        return error is ValidationException || this.originalErrorHandler.HandleError(error);
    }

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {
        ValidationException validationException = error as ValidationException;
        if (validationException != null)
        {
            fault = Message.CreateMessage(version, null, new ValidationErrorBodyWriter(validationException));
            HttpResponseMessageProperty prop = new HttpResponseMessageProperty();
            prop.StatusCode = HttpStatusCode.BadRequest;
            prop.Headers[HttpResponseHeader.ContentType] = "application/json; charset=utf-8";
            fault.Properties.Add(HttpResponseMessageProperty.Name, prop);
            fault.Properties.Add(WebBodyFormatMessageProperty.Name, new WebBodyFormatMessageProperty(WebContentFormat.Json));
        }
        else
        {
            this.originalErrorHandler.ProvideFault(error, version, ref fault);
        }
    }

    class ValidationErrorBodyWriter : BodyWriter
    {
        private ValidationException validationException;
        Encoding utf8Encoding = new UTF8Encoding(false);

        public ValidationErrorBodyWriter(ValidationException validationException)
            : base(true)
        {
            this.validationException = validationException;
        }

        protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
        {
            writer.WriteStartElement("root");
            writer.WriteAttributeString("type", "object");

            writer.WriteStartElement("ErrorMessage");
            writer.WriteAttributeString("type", "string");
            writer.WriteString(this.validationException.ValidationResult.ErrorMessage);
            writer.WriteEndElement();

            writer.WriteStartElement("MemberNames");
            writer.WriteAttributeString("type", "array");
            foreach (var member in this.validationException.ValidationResult.MemberNames)
            {
                writer.WriteStartElement("item");
                writer.WriteAttributeString("type", "string");
                writer.WriteString(member);
                writer.WriteEndElement();
            }
            writer.WriteEndElement();

            writer.WriteEndElement();
        }
    }
}
于 2012-09-17T13:31:23.420 に答える