2013-03-08 2 views
1

У меня, кажется, проблема с получением интерфейса IErrorHandler. Мой кодWCF исключение IErrorHandler не получает вызов

using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.Diagnostics; 
using System.ServiceModel; 
using System.ServiceModel.Channels; 
using System.ServiceModel.Configuration; 
using System.ServiceModel.Description; 
using System.ServiceModel.Dispatcher; 

namespace WcfService3 
{ 
    public class Service1 : IService1 
    { 
     public string GetData(int value) 
     { 
      throw new Exception("asdf"); 

     } 
    } 

    public class MyErrorHandler : IErrorHandler 
    { 
     public MyErrorHandler() 
     { 
      string Hello = ""; 
     } 
     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"); 
        } 
       } 
      } 
     } 
    } 
} 

Мой web.config является:

<?xml version="1.0"?> 
<configuration> 

    <appSettings> 
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" /> 
    </appSettings> 
    <system.web> 
    <compilation debug="true" targetFramework="4.5" /> 
    <httpRuntime targetFramework="4.5"/> 
    </system.web> 
    <system.serviceModel> 
     <services> 
    <service name="WcfService3.Service1"> 
     <endpoint address="" 
       binding="basicHttpBinding" 
       contract="WcfService3.IService1" /> 
    </service> 
    </services> 

    <behaviors> 
     <serviceBehaviors> 
     <behavior> 
      <!-- To avoid disclosing metadata information, set the values below to false before deployment --> 
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="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="false"/> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
     <extensions> 
    <behaviorExtensions> 
     <add name="errorHandler" 
      type="WcfService3.ErrorHandlerExtension, WcfService3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" /> 
    </behaviorExtensions> 
    </extensions> 

    <protocolMapping> 
     <add binding="basicHttpsBinding" scheme="https" /> 
    </protocolMapping>  
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /> 
    </system.serviceModel> 
    <system.webServer> 
    <modules runAllManagedModulesForAllRequests="true"/> 
    <!-- 
     To browse web app root directory during debugging, set the value below to true. 
     Set to false before deployment to avoid disclosing web app folder information. 
     --> 
    <directoryBrowse enabled="true"/> 
    </system.webServer> 

</configuration> 

Мой интерфейс WCF является:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Runtime.Serialization; 
using System.ServiceModel; 
using System.ServiceModel.Web; 
using System.Text; 

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

    [DataContract] 
    public class MyFault 
    { 

    } 

} 

Мой вопрос в IErrorHandler в WCF, если есть какие-либо исключения во время WCF, функция HandlerError() предполагает, что вы вызываете сначала, как приложение класса C#, UnhandledException, а затем служба должна сработать правильно? В приведенном выше коде во время вызова службы генерируется исключение, но моя функция HandlerError не получает вызов до того, как будет выбрано исключение? Моя цель - зарегистрировать ошибку, и служба WCF может выбросить необработанное исключение и сбой. Во время отладки я ожидал, что точка останова посетит функцию HandleError, но эта функция не будет вызвана, и появится только исключение?

ответ

2

Вам не хватает <errorHandler /> в разделе behavior?

<behavior> 
    <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/> 
    <serviceDebug includeExceptionDetailInFaults="false"/> 
    <!-- HERE --> 
    <errorHandler /> 
    <!-- HERE --> 
</behavior> 

Полный ответ here. Плюс 1 к этому ответу.

Смежные вопросы