2011-04-26 34 views
3

我有一个WCF服务,我有一个IErrorHandler绑定到它的FaultContract,它工作得很好。出于某种原因,我不知道,它在运行时停止了绑定。当我在ApplyDispatchBehaviorValidate上放置断点时,当我开始调试(它用于停止)时,它们不会被调用,所以当出现错误时我的异常不会被处理。
我最初遵循this blog post来实现它,它运行良好,但是当我添加第二个接口/端点时,它停止工作。我根据this SO post更改了我的所有代码,但无济于事。这开始发生的另一件事是,当我打开与Microsoft服务配置编辑器web.config中,我得到的错误:
IErrorHandler没有绑定,也没有处理错误

The 'TestAppServer, Version 1.0.0.0, Culture=neutral, PublicKeyToken=null' assembly could not be found. Do you want to locate it? If you select 'No', you will not be prompted for the same assembly again. To avoid seeing this message every time the system cannot fund the assembly, please copy the assembly file to the same folder as the configuration file. 

上面的错误开始发生后,我加入了第二个端点/接口,当我在我的WCF服务上失去了错误处理。下面是我的web配置:

<?xml version="1.0"?> 
<configuration> 
    <system.web> 
    <compilation debug="true" targetFramework="4.0" /> 
    </system.web> 
    <system.serviceModel> 
    <extensions> 
     <behaviorExtensions> 
     <add name="ServiceErrorHandler" type="company.Test.appserver.implementation.ServiceErrorHandlerBehaviorExtensionElement, TestAppServer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> 
     </behaviorExtensions> 
    </extensions> 
    <bindings> 
     <basicHttpBinding> 
     <binding name="SimpleBinding" /> 
     </basicHttpBinding> 
    </bindings> 
    <services> 
     <service behaviorConfiguration="DefaultBehavior" name="company.Test.appserver.implementation.TestUpdate"> 
     <endpoint address="udt" binding="basicHttpBinding" bindingConfiguration="SimpleBinding" 
      name="TestUpdate" bindingNamespace="http://company/Test/update/2011/04" 
      contract="company.Test.appserver.interfaces.ITestUpdate" /> 
     <endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="" 
      name="TestUpdateMex" bindingNamespace="http://company/Test/update/2011/04" 
      contract="IMetadataExchange" /> 
     </service> 
     <service behaviorConfiguration="DefaultBehavior" name="company.Test.appserver.implementation.TestTransaction"> 
     <endpoint address="udt" binding="basicHttpBinding" bindingConfiguration="SimpleBinding" 
      name="TestTransacao" bindingNamespace="http://company/Test/transaction/2011/04" 
      contract="company.Test.appserver.interfaces.ITestTransacao" /> 
     <endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="" 
      name="TestTransacaoMex" bindingNamespace="http://company/Test/transaction/2011/04" 
      contract="IMetadataExchange" /> 
     </service> 
    </services> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior name="DefaultBehavior"> 
      <serviceMetadata httpGetEnabled="true" httpGetBinding="webHttpBinding" 
      httpGetBindingConfiguration="" /> 
      <serviceDebug includeExceptionDetailInFaults="true" /> 
     </behavior> 
     <behavior name=""> 
      <serviceMetadata httpGetEnabled="true" httpGetBinding="webHttpBinding" 
      httpGetBindingConfiguration="" /> 
      <serviceDebug includeExceptionDetailInFaults="false" /> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> 
    </system.serviceModel> 
<system.webServer> 
    <modules runAllManagedModulesForAllRequests="true"/> 
    </system.webServer> 
</configuration> 

下面是我的错误处理代码:

namespace company.Test.appserver.implementation 
{ 
    public class ServiceErrorHandlerBehaviorExtensionElement : BehaviorExtensionElement, IServiceBehavior 
    { 
    public override Type BehaviorType 
    { 
     get { return typeof(TestErrorHandler); } 
    } 

    protected override object CreateBehavior() 
    { 
     return new TestErrorHandler(); 
    } 

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

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

    } 

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) 
    { 
     IErrorHandler errorHandlerInstance = GetInstance(); 
     foreach (ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers) 
     { 
     ChannelDispatcher cd = cdb as ChannelDispatcher; 

     if (cd != null) 
     { 
      cd.ErrorHandlers.Add(errorHandlerInstance); 
     } 
     } 
    } 

    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) 
    { 
     foreach (var svcEndpoint in serviceDescription.Endpoints) 
     { 
     if (svcEndpoint.Contract.Name != "IMetadataExchange") 
     { 
      foreach (var opDesc in svcEndpoint.Contract.Operations) 
      { 
      if (opDesc.Faults.Count == 0) 
      { 
       string msg = string.Format(""); 
      } 
      } 
     } 
     } 
    } 
    } 

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

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault) 
    { 
     if (!(error is FaultException)) 
     { 
     ClsTestFaultContract exContract = new ClsTestFaultContract(); 

     FaultException<ClsTestFaultContract> fex = 
      new FaultException<ClsTestFaultContract>(exContract, exContract.DescricaoErro, 
      new FaultCode(Convert.ToString(exContract.CodigoErro))); 
     MessageFault msgFault = fex.CreateMessageFault(); 
     fault = Message.CreateMessage(version, msgFault, ErrorHandlerConstant.FaultAction); 
     } 
    } 
    } 
} 

下面是我的接口之一:我已经浪费了无数个小时

namespace company.Test.appserver.interfaces 
{ 
    [ServiceContract(Namespace = "http://company/Test/transaction/2011/04", 
      Name = "ITestTransacao", SessionMode = SessionMode.Allowed)] 
    public interface ITestTransacao 
    { 
    [OperationContract] 
    [FaultContract(typeof(ClsTestFaultContract), Action = ErrorHandlerConstant.FaultAction)] 
    Int32 RegistrarTransacao(String Param1, String Param2, String Param3, Int32 Param4); 
    [OperationContract] 
    [FaultContract(typeof(ClsTestFaultContract), Action = ErrorHandlerConstant.FaultAction)] 
    void ConfirmarTransacao(String Param1, String Param2, Int32 Param3, String Param4, String Param5); 
    [OperationContract] 
    [FaultContract(typeof(ClsTestFaultContract), Action = ErrorHandlerConstant.FaultAction)] 
    void CancelarTransacao(String Param1, String Param2, String Param3, Int32 Param4, String Param5 = ""); 
    } 
} 

,我似乎无法弄清楚发生了什么事情,打破了我的错误处理,这很好。 韩国社交协会这么多的帮助

编辑

我张贴工作代码下面,我得到的帮助后。 TKS所以再多... 下面是正确的错误处理程序:

namespace company.Test.appserver.implementation 
{ 
    public class ServiceErrorHandlerBehaviorExtensionElement : BehaviorExtensionElement 
    { 
    public override Type BehaviorType 
    { 
     get { return typeof(TestErrorHandler); } 
    } 

    protected override object CreateBehavior() 
    { 
     return new TestErrorHandler(); 
    } 
    } 

    public class TestErrorHandler : ServiceErrorHandlerBehaviorExtensionElement, IErrorHandler, IServiceBehavior 
    { 
    public bool HandleError(Exception error) 
    { 
     return true; 
    } 

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault) 
    { 
     if (!(error is FaultException)) 
     { 
     ClsTestFaultContract exContract = new ClsTestFaultContract(); 

     FaultException<ClsTestFaultContract> fex = 
      new FaultException<ClsTestFaultContract>(exContract, exContract.DescricaoErro, 
      new FaultCode(Convert.ToString(exContract.CodigoErro))); 
     MessageFault msgFault = fex.CreateMessageFault(); 
     fault = Message.CreateMessage(version, msgFault, ErrorHandlerConstant.FaultAction); 
     } 
    } 

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

    } 

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) 
    { 
     foreach (ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers) 
     { 
     ChannelDispatcher cd = cdb as ChannelDispatcher; 

     if (cd != null) 
     { 
      cd.ErrorHandlers.Add(this); 
     } 
     } 
    } 

    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) 
    { 
     foreach (var svcEndpoint in serviceDescription.Endpoints) 
     { 
     if (svcEndpoint.Contract.Name != "IMetadataExchange") 
     { 
      foreach (var opDesc in svcEndpoint.Contract.Operations) 
      { 
      if (opDesc.Faults.Count == 0) 
      { 
       string msg = string.Format(""); 
      } 
      } 
     } 
     } 
    } 
    } 
} 

及以下正确的web.config

<?xml version="1.0"?> 
<configuration> 
    <system.web> 
    <compilation debug="true" targetFramework="4.0" /> 
    </system.web> 
    <system.serviceModel> 
    <extensions> 
     <behaviorExtensions> 
     <add name="ServiceErrorHandler" type="company.Test.appserver.implementation.ServiceErrorHandlerBehaviorExtensionElement, TestAppServer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> 
     </behaviorExtensions> 
    </extensions> 
    <bindings> 
     <basicHttpBinding> 
     <binding name="SimpleBinding" /> 
     </basicHttpBinding> 
    </bindings> 
    <services> 
     <service behaviorConfiguration="DefaultBehavior" name="company.Test.appserver.implementation.TestUpdate"> 
     <endpoint address="udt" binding="basicHttpBinding" bindingConfiguration="SimpleBinding" 
      name="TestUpdate" bindingNamespace="http://company/Test/update/2011/04" 
      contract="company.Test.appserver.interfaces.ITestUpdate" /> 
     <endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="" 
      name="TestUpdateMex" bindingNamespace="http://company/Test/update/2011/04" 
      contract="IMetadataExchange" /> 
     </service> 
     <service behaviorConfiguration="DefaultBehavior" name="company.Test.appserver.implementation.TestTransaction"> 
     <endpoint address="udt" binding="basicHttpBinding" bindingConfiguration="SimpleBinding" 
      name="TestTransacao" bindingNamespace="http://company/Test/transaction/2011/04" 
      contract="company.Test.appserver.interfaces.ITestTransacao" /> 
     <endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="" 
      name="TestTransacaoMex" bindingNamespace="http://company/Test/transaction/2011/04" 
      contract="IMetadataExchange" /> 
     </service> 
    </services> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior name="DefaultBehavior"> 
      <serviceMetadata httpGetEnabled="true" httpGetBinding="webHttpBinding" 
      httpGetBindingConfiguration="" /> 
      <serviceDebug includeExceptionDetailInFaults="true" /> 
      <ServiceErrorHandler /> 
     </behavior> 
     <behavior name=""> 
      <serviceMetadata httpGetEnabled="true" httpGetBinding="webHttpBinding" 
      httpGetBindingConfiguration="" /> 
      <serviceDebug includeExceptionDetailInFaults="false" /> 
      <ServiceErrorHandler /> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> 
    </system.serviceModel> 
<system.webServer> 
    <modules runAllManagedModulesForAllRequests="true"/> 
    </system.webServer> 
</configuration> 

回答

4

您的配置文件的ServiceErrorHandler行为扩展注册,但它不是实际在< serviceBehaviors/>下的任何集合中使用它。

+0

就是这样吗?什么不见​​了?在配置第二个端点时,我必须将其擦除。 Tks太多了 – Pascal 2011-04-26 12:52:27

+0

我知道了...... Tks太多了。只注意到了缺失的行为。我要用正确的代码编辑我的问题。 – Pascal 2011-04-26 15:40:05

+0

感谢您编辑您的问题,这也解决了我的问题! – NibblyPig 2013-06-03 12:59:31

相关问题