3 Stimmen

wcf rest ierrorhandler webfaultexception

Ich habe einen WCF 4 Rest-Dienst, der von einem Java-Client und auch einem c# mvc3-Client konsumiert werden soll. Der Inhalt der Antwort muss als json zurückgegeben werden.

Ich möchte in der Lage sein, alle Ausnahmen/Fehler auf konsistente Art und Weise an die Kunden zurückzugeben. Ich habe gelesen, dass WebFaultException verwendet werden sollte und in der Tat funktioniert es gut.

Allerdings möchte ich nicht meine Anwendungslogik Projekt mit WebFaultExceptions zu verschmutzen, wie es von einem nicht-Web-Projekt verwendet werden kann.

Ich habe daher die Implementierung von IErrorHandler im WCF-Rest-Dienst in Betracht gezogen, um JEDE Ausnahme abzufangen und dann für bestimmte Ausnahmen, z. B. ValidationException, die Ausnahme als Fehler in einer WebFaultException verpackt zurückzugeben. Dies scheint jedoch nicht zu funktionieren, und ich erhalte die folgende Http 504-Antwort, wenn das Formular fiddler aufgerufen wird

[Fiddler] ReadResponse() ist fehlgeschlagen: Der Server hat keine Antwort für diese Anfrage zurückgegeben.

Ich habe den Code auf das Nötigste reduziert, um zu zeigen, was ich im Wesentlichen tue.

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()));
}

Was mache ich falsch?

2voto

Cybermaxs Punkte 24028

Hier ist ein Beispielcode aus Carlos' Blog . Es hilft mir in der Vergangenheit.

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();
        }
    }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X