2010-06-14 19 views
23

Đã đọc xung quanh trên IErrorHandler và muốn đi tuyến đường cấu hình. vì vậy, tôi đã đọc những điều sau đây trong một nỗ lực để thực hiện nó.IErrorHandler dường như không xử lý các lỗi của tôi trong WCF .. bất kỳ ý tưởng nào?

MSDN

Keyvan Nayyeri blog about the type defintion

Rory Primrose Blog

này về cơ bản là chỉ là ví dụ MSDN bọc trong một lớp kế thừa IErrorHandler và IServiceBehaviour ... thì đây được gói trong các yếu tố mở rộng được thừa kế từ BehaviourExtensionElement bị cáo buộc cho phép tôi thêm phần tử vào web.config. Tôi đã bỏ lỡ điều gì?

Tôi đã có nó để biên dịch và từ các lỗi khác nhau tôi đã cố định có vẻ như WCF thực sự đang tải trình xử lý lỗi. Vấn đề của tôi là ngoại lệ mà tôi đang ném để xử lý trong trình xử lý lỗi không nhận được ngoại lệ được truyền cho nó.

Việc triển khai dịch vụ của tôi chỉ đơn giản gọi một phương thức trên một lớp khác ném ArgumentOutOfRangeException - tuy nhiên ngoại lệ này không bao giờ được xử lý bởi trình xử lý.

web.config My

<system.serviceModel> 
    <bindings> 
     <basicHttpBinding> 
     <binding name="basic"> 
      <security mode="None" />      
     </binding> 
     </basicHttpBinding> 
    </bindings> 
    <extensions> 
     <behaviorExtensions> 
     <add name="customHttpBehavior" 
      type="ErrorHandlerTest.ErrorHandlerElement, ErrorHandlerTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> 
     </behaviorExtensions> 
    </extensions> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior name="exceptionHandlerBehaviour">   
      <serviceMetadata httpGetEnabled="true"/> 
      <!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information --> 
      <serviceDebug includeExceptionDetailInFaults="true"/> 
      <customHttpBehavior /> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    <services> 
     <service behaviorConfiguration="exceptionHandlerBehaviour" name="ErrorHandlerTest.Service1"> 
     <endpoint binding="basicHttpBinding" bindingConfiguration="basic" contract="ErrorHandlerTest.IService1" /> 
     </service> 
    </services> 

Dịch vụ Hợp đồng

[ServiceContract] 
public interface IService1 
{ 
    [OperationContract] 
    [FaultContract(typeof(GeneralInternalFault))] 
    string GetData(int value); 
} 

Các ErrorHandler lớp

public class ErrorHandler : IErrorHandler , IServiceBehavior 
{ 
    public bool HandleError(Exception error) 
    { 
     Console.WriteLine("caught exception {0}:",error.Message); 
     return true; 
    } 

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault) 
    { 
     if (fault!=null) 
     { 
      if (error is ArgumentOutOfRangeException) 
      { 
       var fe = new FaultException<GeneralInternalFault>(new GeneralInternalFault("general internal fault.")); 
       MessageFault mf = fe.CreateMessageFault(); 

       fault = Message.CreateMessage(version, mf, fe.Action); 

      } 
      else 
      { 
       var fe = new FaultException<GeneralInternalFault>(new GeneralInternalFault(" the other general internal fault.")); 
       MessageFault mf = fe.CreateMessageFault(); 

       fault = Message.CreateMessage(version, mf, fe.Action); 
      } 
     } 
    } 

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

    } 

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) 
    { 
     IErrorHandler errorHandler = new ErrorHandler(); 
     foreach (ChannelDispatcherBase channelDispatcherBase in serviceHostBase.ChannelDispatchers) 
     { 
      ChannelDispatcher channelDispatcher = channelDispatcherBase as ChannelDispatcher; 
      if (channelDispatcher != null) 
      { 
       channelDispatcher.ErrorHandlers.Add(errorHandler); 
      } 
     } 
    } 


    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) 
    { 


    } 
} 

Và hành vi mở rộng phần tử

public class ErrorHandlerElement : BehaviorExtensionElement 
    { 
     protected override object CreateBehavior() 
     { 
      return new ErrorHandler(); 
     } 

     public override Type BehaviorType 
     { 
      get { return typeof(ErrorHandler); } 
     } 
    } 

Trả lời

43

Dưới đây là một ví dụ làm việc đầy đủ:

[ServiceContract] 
public interface IService1 
{ 
    [OperationContract] 
    [FaultContract(typeof(MyFault))] 
    string GetData(int value); 
} 

[DataContract] 
public class MyFault 
{ 

} 

public class Service1 : IService1 
{ 
    public string GetData(int value) 
    { 
     throw new Exception("error"); 
    } 
} 

public class MyErrorHandler : IErrorHandler 
{ 
    public bool HandleError(Exception error) 
    { 
     return true; 
    } 

    public void ProvideFault(Exception error, MessageVersion version, ref Message msg) 
    { 
     var vfc = new MyFault(); 
     var fe = new FaultException<MyFault>(vfc); 
     var fault = fe.CreateMessageFault(); 
     msg = Message.CreateMessage(version, fault, "http://ns"); 
    } 
} 

public class ErrorHandlerExtension : BehaviorExtensionElement, IServiceBehavior 
{ 
    public override Type BehaviorType 
    { 
     get { return GetType(); } 
    } 

    protected override object CreateBehavior() 
    { 
     return this; 
    } 

    private IErrorHandler GetInstance() 
    { 
     return new MyErrorHandler(); 
    } 

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

    void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) 
    { 
     IErrorHandler errorHandlerInstance = GetInstance(); 
     foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers) 
     { 
      dispatcher.ErrorHandlers.Add(errorHandlerInstance); 
     } 
    } 

    void IServiceBehavior.Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) 
    { 
     foreach (ServiceEndpoint endpoint in serviceDescription.Endpoints) 
     { 
      if (endpoint.Contract.Name.Equals("IMetadataExchange") && 
       endpoint.Contract.Namespace.Equals("http://schemas.microsoft.com/2006/04/mex")) 
       continue; 

      foreach (OperationDescription description in endpoint.Contract.Operations) 
      { 
       if (description.Faults.Count == 0) 
       { 
        throw new InvalidOperationException("FaultContractAttribute not found on this method"); 
       } 
      } 
     } 
    } 
} 

và web.config:

<system.serviceModel> 
    <services> 
    <service name="ToDD.Service1"> 
     <endpoint address="" 
       binding="basicHttpBinding" 
       contract="ToDD.IService1" /> 
    </service> 
    </services> 

    <behaviors> 
    <serviceBehaviors> 
     <behavior> 
     <serviceMetadata httpGetEnabled="true"/> 
     <serviceDebug includeExceptionDetailInFaults="false"/> 
     <errorHandler /> 
     </behavior> 
    </serviceBehaviors> 
    </behaviors> 
    <extensions> 
    <behaviorExtensions> 
     <add name="errorHandler" 
      type="ToDD.ErrorHandlerExtension, ToDD, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> 
    </behaviorExtensions> 
    </extensions> 

</system.serviceModel> 
+0

cảm ơn bạn rất nhiều, xin lỗi đã quá lâu để tôi trả lời thiết lập của tôi tại nơi làm việc là knackered. Điều này làm việc tốt trên thiết lập của tôi ở nhà mặc dù. –

+0

Cảm ơn ví dụ đầy đủ. Điều này làm việc như một say mê! – Stewie

+0

Làm việc cho tôi, mặc dù visual studio phàn nàn "hành vi của phần tử có errorhandler phần tử con không hợp lệ" - Tôi chỉ bỏ qua và trong thời gian chạy nó hoạt động. – BornToCode

1

Bạn có thể xem liệu web.config có đang hoạt động và đang tải hay không bằng cách thêm bản in hoặc điểm ngắt cho ứng dụng ApplyDispatchBehavior và xem liệu nó có được in/nhấn khi dịch vụ đầu tiên mở ra hay không. Vì vậy, nó đang được nạp?

Tôi cũng sẽ thêm bản in/điểm ngắt tại ProvideFault.

+0

Các breakpoint không có được hit. điểm dừng duy nhất mà tôi có thể bị tấn công là chính bản thân webservice. –

Các vấn đề liên quan