2011-04-26 5 views
3

私はWCFサービスを持っていて、IErrorHandlerをバインドしたFaultContractを持っています。何らかの理由で、私はそれがわからない、それは実行時にバインドされなくなった。 ApplyDispatchBehaviorValidateにブレークポイントを配置すると、デバッグを開始するときにブレークポイントが呼び出されることはありません(停止するために使用されるため)、エラーが発生したときに例外が処理されません。
私は最初にthis blog postを実装して実装しましたが、うまくいきましたが、2番目のインターフェイス/エンドポイントを追加すると機能しなくなりました。 this SO postに基づいてコードをすべて変更しましたが、役に立たなくなりました。起こって始めたもう一つは、私は、Microsoft Service Configuration Editorので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. 

私はとき、第2のエンドポイント/インターフェースを追加した後、上記のエラーが起こっ開始しましたWCFサービスでエラー処理が失われました。以下は

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

が私のインターフェースの一つである:

以下
<?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> 

は私のエラーハンドラのコードです:以下は私のウェブconfigです

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

私は数え切れないほどの時間を無駄にしました、私はエラー処理を壊してしまったことが分かりませんでした。うまくいきました。私は私が得た助けた後、作業コードの下に掲示しています任意の助け

EDIT

用SO MUCH TKS。ずっと再び...以下 が正しいエラーハンドラである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

これはすべてですか?何が欠けている? 2番目のエンドポイントを設定するときに間違って削除したはずです。 Tks so much – Pascal

+0

私はそれを得ました... Tksはそんなに。ちょうど行方不明の行動に気づいた。私は正しいコードで私の質問を編集するつもりです。 – Pascal

+0

あなたの質問を編集していただきありがとうございます、これも私の問題を解決! – NibblyPig

関連する問題