IErrorHandler不';我似乎没有处理我在WCF中的错误。。有什么想法吗?

IErrorHandler不';我似乎没有处理我在WCF中的错误。。有什么想法吗?,wcf,ierrorhandler,Wcf,Ierrorhandler,一直在阅读IErrorHandler的相关信息,并希望转到配置路径。 因此,为了实现它,我阅读了以下内容 这基本上只是包装在继承IErrorHandler和IServiceBehaviour的类中的msdn示例。。。然后将其包装在继承自BehaviorExtensionElement的扩展元素中,以允许我将该元素添加到web.config中。我错过了什么 我已经编译了它,从我修复的各种错误来看,似乎WCF实际上正在加载错误处理程序。我的问题是,我要在错误处理程序中处理的异常不存在;无法将异

一直在阅读IErrorHandler的相关信息,并希望转到配置路径。 因此,为了实现它,我阅读了以下内容

这基本上只是包装在继承IErrorHandler和IServiceBehaviour的类中的msdn示例。。。然后将其包装在继承自BehaviorExtensionElement的扩展元素中,以允许我将该元素添加到web.config中。我错过了什么

我已经编译了它,从我修复的各种错误来看,似乎WCF实际上正在加载错误处理程序。我的问题是,我要在错误处理程序中处理的异常不存在;无法将异常传递给它

我的服务实现只是在另一个类上调用一个抛出ArgumentOutOfRangeException的方法,但是这个异常永远不会被处理程序处理

我的web.config

<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>
ErrorHandler类

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)
    {


    }
}

您可以通过向ApplyDispatchBehavior添加一个打印或断点来查看web.config是否正在工作和加载,并查看该服务首次打开时是否打印/命中。那么它正在加载吗


我还要在默认设置下添加一个打印/断点。

下面是一个完整的工作示例:

[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");
                }
            }
        }
    }
}
[服务合同]
公共接口IService1
{
[经营合同]
[FaultContract(类型(MyFault))]
字符串GetData(int值);
}
[数据合同]
公共类MyFault
{
}
公共类服务1:IService1
{
公共字符串GetData(int值)
{
抛出新异常(“错误”);
}
}
公共类MyErrorHandler:IErrorHandler
{
公共布尔句柄错误(异常错误)
{
返回true;
}
public void providefaulture(异常错误,MessageVersion,ref Message msg)
{
var vfc=新的MyFault();
var fe=新故障异常(vfc);
var fault=fe.CreateMessageFault();
msg=Message.CreateMessage(版本,错误,“http://ns");
}
}
公共类ErrorHandlerExtension:BehaviorExtensionElement,IServiceBehavior
{
公共重写类型BehaviorType
{
获取{return GetType();}
}
受保护的重写对象CreateBehavior()
{
归还这个;
}
私有IErrorHandler GetInstance()
{
返回新的MyErrorHandler();
}
void IServiceBehavior.AddBindingParameters(ServiceDescription ServiceDescription,ServiceHostBase ServiceHostBase,集合终结点,BindingParameterCollection bindingParameters)
{
}
无效IServiceBehavior.ApplyDispatchBehavior(ServiceDescription ServiceDescription,ServiceHostBase ServiceHostBase)
{
IErrorHandler errorHandlerInstance=GetInstance();
foreach(serviceHostBase.ChannelDispatchers中的ChannelDispatcher)
{
dispatcher.ErrorHandlers.Add(errorHandlerInstance);
}
}
无效IServiceBehavior.Validate(ServiceDescription ServiceDescription,ServiceHostBase ServiceHostBase)
{
foreach(serviceDescription.Endpoints中的ServiceEndpoint端点)
{
if(endpoint.Contract.Name.Equals(“IMetadataExchange”)&&
endpoint.Contract.Namespace.Equals(“http://schemas.microsoft.com/2006/04/mex"))
继续;
foreach(endpoint.Contract.Operations中的操作描述)
{
如果(description.Faults.Count==0)
{
抛出新的InvalidOperationException(“在此方法上未找到FaultContractAttribute”);
}
}
}
}
}
和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>


断点不会被击中。我能找到的唯一断点是Web服务本身。非常感谢,很抱歉,我花了这么长时间才回答,我的工作设置已经没有了。不过,这在我的家庭设置中运行良好。虽然visual studio抱怨“元素行为具有无效的子元素errorhandler”,但对我来说仍然有效-我只是忽略了它,并且在运行时它可以工作。如何使它返回自定义类型的json对象(例如MyFault)?下面是如何使它返回json:
[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");
                }
            }
        }
    }
}
<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>