IErrorHandler doesn't seem to be handling my errors in WCF .. any ideas?

前端 未结 2 999
清歌不尽
清歌不尽 2020-12-04 22:25

Have been reading around on IErrorHandler and want to go the config route. so, I have read the following in an attempt to implement it.

MSDN

Keyvan Nayyeri

相关标签:
2条回答
  • 2020-12-04 22:39

    Here's a full working example:

    [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");
                    }
                }
            }
        }
    }
    

    and 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 讨论(0)
  • 2020-12-04 23:02

    You can see if the web.config is working and loading by adding a print or a breakpoint to the ApplyDispatchBehavior, and see if that gets printed/hit when the service first opens. So is it being loaded?

    I'd add a print/breakpoint at ProvideFault, as well.

    0 讨论(0)
提交回复
热议问题