2010-12-16 3 views
8

저는 WCF REST 서비스의 백엔드 인 많은 레거시 코드를 가지고 있습니다. 이전에 일반적인 WCF 서비스 백엔드였습니다. 모든 메소드에서 예외를 catch하고 분석하는 메커니즘을 구현하려고합니다. 알려진 오류로 밝혀지면 처리되어 친숙한 오류로 바뀝니다.WCF REST Services - 일반 예외 처리

나는 '일반적인'예외 대신 FaultException 또는 WebProtocolException을 던질 수 있지만 예외가 코드 전체에 던져지고 그 모두를 찾는 것이 상당히 힘든 옵션이라는 것을 알고 있습니다.

표준 WebHttpBehavior.AddServerErrorHandlers 메서드를 재정의하고 끝점 디스패처 오류 처리기 컬렉션에 내 오류 처리기 (IErrorHandler 구현)를 추가하는 새로운 동작을 만드는 끝점 동작 확장을 추가하려고했습니다. 오류 처리기 내부에서 예외를 분석하고이 예외를 기반으로 원하는 오류를 만들거나 작성하지 않습니다.

이 메커니즘이 알려진 예외에 대한 사용자 지정 데이터를 반환 할 것으로 예상했지만 잘못되었습니다. 좋은 옛날 마이크로 소프트는 피할 수없는 훌륭한 WebHttpBehavior2을 구현했다. 무조건적으로 엔드 포인트 디스패처 오류 처리기 모음의 끝에 Microsoft.ServiceModel.Web.WebErrorHandler 내부를 추가한다. 이 처리기는 이전에 실행 된 모든 처리기를 무시하고 작은 예외 집합 만 인식하며 대다수는 "내부 서버 오류"로 해석됩니다.

질문은 내가 올바른 경로에 있는지 여부와 WCF REST 메커니즘에서이 처리기를 사용하지 않도록 설정하거나 새로운 Exception으로 도입하는 방법이 있습니다 (예 : 예외가 발견되면 해당 코드가 처음 처리됩니다. 예를 들어 FaultException을 던지거나 반환하는 경우이 새로운 예외는 원래 예외 대신 Microsoft.ServiceModel.Web.WebErrorHandler에 제공됩니다. IErrorHandler 및 작동 기능 확장을 사용한 모든 실험이 쓸모 없다면 무엇이 대안입니까? 다시 말하지만, 로직을 던지는 예외를 수정하고 싶지는 않습니다. 한 곳에서 예외를 찾아 처리해야합니다.

고맙습니다.

답변

7

WCF SOAP 서비스를 REST로 변경하면 오류보고 및 처리의 전체적인 사고 방식이 변경됩니다.

SOAP에서 결함은 계약의 일부입니다. REST에서는 HTTP 응답 코드 및 설명으로 출력하는 코드가됩니다.

catch (Exception e) 
{ 
    Trace.WriteLine(e.ToString()); 

    OutgoingWebResponseContext response = WebOperationContext.Current.OutgoingResponse; 
    response.StatusCode = System.Net.HttpStatusCode.UnsupportedMediaType; // or anything you want 
    response.StatusDescription = e.Message; 
    return null; // I was returning a class 
} 

그래서 내가 당신을 위해 관련 오류 코드를 생성하고 응답에 넣어 도우미 코드를 만들 제안 : 여기

는 캐치 조각입니다.

+0

이러한 캐치는 모든 서비스 방법에 추가되어야합니다. 맞습니까? 아니면 모든 예외를 처리하기 위해 한 번만 쓸 수있는 방법이 있습니까? 모든 예외에 대해 공통 처리기를 정의했기 때문에 동작 기반 방식이 좋았으며 각 단일 메서드에 대한 예외 처리 및 처리에 대해 걱정할 필요가 없었습니다. 가장 좋은 점은 엔드 포인트의 모든 서비스에 대해 하나의 프로세서를 정의했다는 것입니다. 당신의 접근 방식을 사용하여 이것을 달성 할 수는 없습니까? –

+0

'StatusDescription'을 설정해도 효과가 없습니다! 응답에는 항상 일반 상태 설명이 있습니다. 어쨌든 그것을 고칠 수 있습니까? – Hemant

+0

있습니다.바이올린을 사용하여 서버의 보내는 메시지에서이를 확인할 수 있습니다. 그러나 다양한 브라우저 또는 구현이 설명을 무시하고 코드를 사용하여 미리 정의 된 메시지에 매핑 할 수 있다는 사실을 발견하게됩니다. 내가 작성한 Android 앱에서이 문제가 발생했으며 설명을 설정하고 메소드 시그니처를 변경하여 문자열을 반환 할 수있었습니다. Yikes! ** 그래서 더 이상 WCF REST를 사용하지 않을 것입니다. ** – Aliostad

2

내가

public class MyServerBehavior : IServiceBehavior { 

     public void AddBindingParameters(ServiceDescription serviceDescription, 
      ServiceHostBase serviceHostBase, 
      Collection<ServiceEndpoint> endpoints, 
      BindingParameterCollection bindingParameters) { 

     } 

     public void ApplyDispatchBehavior(ServiceDescription serviceDescription, 
              ServiceHostBase serviceHostBase) { 

      foreach (ChannelDispatcher chDisp in serviceHostBase.ChannelDispatchers) { 
       chDisp.IncludeExceptionDetailInFaults = true; 
       if (chDisp.ErrorHandlers.Count > 0) { 
        // Remove the System.ServiceModel.Web errorHandler 
        chDisp.ErrorHandlers.Remove(chDisp.ErrorHandlers[0]); 
       } 
       // Add new custom error handler 
       chDisp.ErrorHandlers.Add(new MyErrorHandler()); 

      } 

     } 

     public void Validate(ServiceDescription serviceDescription, 
          ServiceHostBase serviceHostBase) { 
     } 

    } 

MyErrorHandler 과거

에 한 일이 IErrorHandler를 구현 내 수업이었다.

+0

이것은 내가 한 것과 매우 비슷하게 보입니다. REST 서비스 또는 SOAP 만 작동 했습니까? REST 서비스에서 작동하는 경우 서비스를 어떻게 구성 했습니까? SOAP 용이라면 고맙겠습니다.하지만 REST는 지금까지 완전히 다른 이야기입니다. –

+1

@Michael 나는 REST 서비스를 위해 그것을했다. 나는 스스로 호스팅했고 실제로 행동을 설정하는 내 자신의 파생 된 서비스 호스트를 만들었습니다. 모든 코드 기반, XML 없음. –

+0

셀프 호스팅, 그게 ... 내가 생각하고 있지만 너무 복잡하다고 생각하는 것입니다. 감사! –