2012-09-17 4 views
3

Java 클라이언트 및 C# mvc3 클라이언트에서 소비하는 WCF 4 Rest 서비스가 있습니다. 응답 내용은 json으로 반환되어야합니다.wcf rest ierrorhandler webfaultexception

모든 예외/오류를 일관된 방식으로 클라이언트에 반환 할 수 있기를 원합니다. 나는 WebFaultException이 사용되어야하고 실제로 잘 동작한다는 것을 읽었다.

그러나 웹 프로젝트가 아닌 다른 프로젝트에서 사용할 수 있으므로 WebFaultExceptions를 사용하여 응용 프로그램 논리 프로젝트를 오염 시키려고하지 않습니다.

따라서 WCF Rest 서비스에서 IErrorHandler를 구현하여 예외를 catch 한 다음 특정 예외 (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())); 
} 

내가 뭘 잘못하고 있니?

+0

IErrorHandler에서 WebFaultException을 사용하는 방법을 알아 냈습니까? – bpeikes

답변

2

다음은 Carlos's blog의 샘플 코드입니다. 나는 과거에 나를 돕는다.

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

나는 전에 Carlos의 솔루션을 보았습니다. IErrorHandler를 구현하면 우리가 본질적으로 메시지를 만들어야한다는 이상한 점이있는 반면, WebFaultException을 서비스에서 직접 사용하는 것, 즉 json/xml 형식을 사용하는 것입니다. 또한 mvc 응용 프로그램은 FaultExceptions (이전에는 Soap 서비스였습니다)를 잡을 수 있었지만 지금 어떻게 잡았는지 잘 모르겠습니다. – swin66

+0

WebFaultException FaultException에서 파생되고 새 인터페이스 IFaultExecption을 구현합니다. 이 방식으로 WCF 4.0이 수정되었습니다 (3.5에서 누락되었습니다). IErrorHandler를 사용하면 생성 된 SOAP 오류를 명시 적으로 제어 할 수 있습니다. RestService 용으로 사용하는 것은 올바른 방법이 아닙니다. 더 나은 휴식 지원을 위해 새로운 Aspnet WebApi를 사용하십시오. – Cybermaxs

+0

프로젝트의이 단계에서 WebApi로 이동하는 것은 선택의 여지가 없습니다. 그래서 만약 내가 카를로스의 솔루션을 사용하면 거기에 mvc 응용 프로그램에서 예외를 잡기 쉬운/허용 된 방법은 무엇입니까? – swin66