好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

WCF服务编程读书笔记(6):错误

WCF服务编程读书笔记(6):错误

Example 6-1. The FaultException<T> class

 using   System;
  using   System.Runtime;
  using   System.Runtime.Serialization;
  using   System.Security;
  using   System.ServiceModel.Channels;

  namespace   System.ServiceModel
{
    [Serializable]   //  More attributes 
     public   class   FaultException : CommunicationException
    {
          public   FaultException( );
          public  FaultException( string   reason);
          public   FaultException(FaultReason reason);
          public   virtual   MessageFault CreateMessageFault( );
          //  More members 
     }

    [Serializable]
      public   class  FaultException<T>  : FaultException
    {
          public   FaultException(T detail);
          public  FaultException(T detail, string   reason);
          public   FaultException(T detail,FaultReason reason);
          //  More members 
     }   
}         

View Code

Example 6-2. Throwing a FaultException<T>

 using   System;
  using   System.Collections.Generic;
  using   System.Linq;
  using   System.Text;
  using   System.ServiceModel;

  namespace   WCFServiceProgramming.Library
{
    [ServiceContract]
      interface   ICalculator
    {
        [OperationContract]
          double  Divide( double  number1,  double   number2);

          //  More methods 
     }
    
      class   Calculator : ICalculator
    {
          public   double  Divide( double  number1,  double   number2)
        {
              if  (number2 ==  0  )
            {
                DivideByZeroException exception  =  new   DivideByZeroException();
                  throw   new  FaultException<DivideByZeroException> (exception);
            }

              return  number1 /  number2;
        }

          //  Rest of the implementation 
     }
} 

View Code

Example 6-3. Defining a fault contract

 using   System;
  using   System.Collections.Generic;
  using   System.Linq;
  using   System.Text;
  using   System.ServiceModel;

  namespace   WCFServiceProgramming.Library
{
    [ServiceContract]
      interface   ICalculator
    {
        [OperationContract]
          double  Add( double  number1,  double   number2);

        [OperationContract]
        [FaultContract(  typeof  (DivideByZeroException))]
          double  Divide( double  number1,  double   number2);

          //  More methods 
     }
} 

View Code

Example 6-4. Including the service exception in the fault message

 using   System;
  using   System.Collections.Generic;
  using   System.Linq;
  using   System.Text;
  using   System.ServiceModel;
  using   System.ServiceModel.Channels;
  using   System.Diagnostics;
  using   System.Runtime.Serialization;

  namespace   WCFServiceProgramming.Library
{
    [ServiceContract]
      public   interface   IMyContract
    {
        [OperationContract]
          void   MethodWithError();
    }

      class   MyService : IMyContract
    {
          public   void   MethodWithError()
        {
            InvalidOperationException exception  =  new  InvalidOperationException( "  Some error  "  );
            ExceptionDetail detail  =  new   ExceptionDetail(exception);

              throw   new  FaultException<ExceptionDetail> (detail, exception.Message);
        }
    }
} 

View Code

Example 6-5. Processing the included exception

 using   System;
  using   System.Collections.Generic;
  using   System.Linq;
  using   System.Text;
  using   System.ServiceModel.Channels;
  using   System.ServiceModel;
  using   System.Runtime.Serialization;
  using   WCFServiceProgramming.Library;
  using   System.Diagnostics;

  namespace   WCFServiceProgramming.Client
{
      class  MyContractClient : ClientBase<IMyContract> , IMyContract
    {
          public   void   MethodWithError()
        {
            Channel.MethodWithError();
        }
    }

      class   Program
    {
          static   void  Main( string  [] args)
        {
            MyContractClient proxy  =  new   MyContractClient();

              try  
            {
                proxy.MethodWithError();
            }
              catch  (FaultException<ExceptionDetail>  exception)
            {
                Debug.Assert(exception.Detail.Type  ==  typeof  (InvalidOperationException).ToString());
                Debug.Assert(exception.Message  ==  "  Some error  "  );
            }
        }
    }
} 

View Code

Example 6-6. SettingIncludeExceptionDetailInFaults to true in debug only

 using   System;
  using   System.Collections.Generic;
  using   System.Linq;
  using   System.Text;
  using   System.ServiceModel;
  using   System.ServiceModel.Channels;
  using   System.Diagnostics;
  using   System.Runtime.Serialization;

  namespace   WCFServiceProgramming.Library
{
    [ServiceContract]
      public   interface   IMyContract
    {
        [OperationContract]
          void   MethodWithError();
    }

      public   static   class   DebugHelper
    {
          public   const   bool  IncludeExceptionDetailInFaults = 
     #if  DEBUG
             true  ;
      #else 
             false  ;
      #endif  
    }

    [ServiceBehavior(IncludeExceptionDetailInFaults  =  DebugHelper.IncludeExceptionDetailInFaults)]
      class   MyService : IMyContract
    {
          public   void   MethodWithError()
        {
            InvalidOperationException exception  =  new  InvalidOperationException( "  Some error  "  );
            ExceptionDetail detail  =  new   ExceptionDetail(exception);

              throw   new  FaultException<ExceptionDetail> (detail, exception.Message);
        }
    }
} 

View Code

Example 6-7. ServiceHost<T> and returning unknown exceptions

 using   System;
  using   System.Collections.Generic;
  using   System.Linq;
  using   System.Text;
  using   System.ServiceModel;
  using   System.ServiceModel.Description;
  using   System.Diagnostics;
  using   System.ServiceModel.Channels;

  namespace   WCFServiceProgramming.Host
{
      public   class  ServiceHost<T>  : ServiceHost
    {
          public   bool   IncludeExceptionDetailInFaults
        {
              set  
            {
                  if  (State ==  CommunicationState.Opened)
                {
                      throw   new  InvalidOperationException( "  Host is already opened  "  );
                }

                ServiceBehaviorAttribute debuggingBehavior  = 
                    Description.Behaviors.Find <ServiceBehaviorAttribute> ();

                debuggingBehavior.IncludeExceptionDetailInFaults  =  value;
            }
              get  
            {
                ServiceBehaviorAttribute debuggingBehavior  = 
                    Description.Behaviors.Find <ServiceBehaviorAttribute> ();

                  return   debuggingBehavior.IncludeExceptionDetailInFaults;
            }
        }
    }
} 

View Code

Example 6-8. Administratively including exceptions in the fault message

 <?  xml version="1.0" encoding="utf-8"   ?> 
 <  configuration  > 
   <  system.serviceModel  > 
     <  services  > 
       <  service   name  ="MyService"   behaviorConfiguration  ="Debugging"  > 
       </  service  > 
     </  services  > 
     <  behaviors  > 
       <  serviceBehaviors  > 
         <  behavior   name  ="Debugging"  > 
           <  serviceDebug   includeExceptionDetailInFaults  ="true"  /> 
         </  behavior  > 
       </  serviceBehaviors  > 
     </  behaviors  > 
   </  system.serviceModel  > 
 </  configuration  > 

View Code

Example 6-9. Callback contract with fault contract

 using   System;
  using   System.Collections.Generic;
  using   System.Linq;
  using   System.Text;
  using   System.ServiceModel;
  using   System.ServiceModel.Channels;
  using   System.Diagnostics;
  using   System.Runtime.Serialization;

  namespace   WCFServiceProgramming.Library
{
    [ServiceContract(CallbackContract  =  typeof  (IMyContractCallback))]
      public   interface   IMyContract
    {
        [OperationContract]
          void   DoSomething();
    }

      interface   IMyContractCallback
    {
        [OperationContract]
        [FaultContract(  typeof  (InvalidOperationException))]
          void   OnCallback();
    }
} 

View Code

Example 6-10. Fault handling in out-of-band invocation

 using   System;
  using   System.Collections.Generic;
  using   System.Linq;
  using   System.Text;
  using   System.ServiceModel;
  using   System.ServiceModel.Channels;
  using   System.Diagnostics;
  using   System.Runtime.Serialization;

  namespace   WCFServiceProgramming.Library
{
    [ServiceContract(CallbackContract  =  typeof  (IMyContractCallback))]
      public   interface   IMyContract
    {
        [OperationContract]
          void   DoSomething();
    }

      interface   IMyContractCallback
    {
        [OperationContract]
        [FaultContract(  typeof  (InvalidOperationException))]
          void   OnCallback();
    }

    [ServiceBehavior(InstanceContextMode  =  InstanceContextMode.PerCall)]
      class   MyService : IMyContract
    {
          static  List<IMyContractCallback> m_Callbacks =
             new  List<IMyContractCallback> ();

          public   void   DoSomething()
        {
            IMyContractCallback callback  = 
                OperationContext.Current.GetCallbackChannel <IMyContractCallback> ();

              if  (m_Callbacks.Contains(callback) ==  false  )
            {
                m_Callbacks.Add(callback);
            }
        }

          public   static   void   CallClients()
        {
            Action <IMyContractCallback> invoke =  delegate  (IMyContractCallback callback)
            {
                  try  
                {
                    callback.OnCallback();
                }
                  catch  (FaultException<InvalidOperationException>  exception)
                { }
                  catch   (FaultException exception)
                { }
                  catch   (CommunicationException exception)
                { }
            };

            m_Callbacks.ForEach(invoke);
        }
    }
} 

View Code

Example 6-11. Creating an alternative fault

 using   System;
  using   System.Collections.Generic;
  using   System.Linq;
  using   System.Text;
  using   System.ServiceModel.Dispatcher;
  using   System.ServiceModel.Channels;
  using   System.ServiceModel;

  namespace   WCFServiceProgramming
{
      class   MyErrorHandler : IErrorHandler
    {
          #region  IErrorHandler Members

         public   bool   HandleError(Exception error)
        {
              //  ... 
             return   true  ;
        }

          public   void  ProvideFault(Exception error, MessageVersion version,  ref   Message fault)
        {
            FaultException < int > faultException =  new  FaultException< int >( 3  );
            MessageFault messageFault  =  faultException.CreateMessageFault();

            fault  =  Message.CreateMessage(version, messageFault, faultException.Action);
        }

          #endregion  
    }
} 

View Code

Example 6-12. Exception promotion

 using   System;
  using   System.Collections.Generic;
  using   System.Linq;
  using   System.Text;
  using   System.ServiceModel.Dispatcher;
  using   System.ServiceModel.Channels;
  using   System.ServiceModel;

  namespace   WCFServiceProgramming
{
      class   MyErrorHandler : IErrorHandler
    {
          #region  IErrorHandler Members

         public   bool   HandleError(Exception error)
        {
              //  ... 
             return   true  ;
        }

          public   void  ProvideFault(Exception error, MessageVersion version,  ref   Message fault)
        {
            FaultException <InvalidOperationException> faultException =
                 new  FaultException<InvalidOperationException>( new   InvalidOperationException(error.Message));
            MessageFault messageFault  =  faultException.CreateMessageFault();

            fault  =  Message.CreateMessage(version, messageFault, faultException.Action);
        }

          #endregion  
    }
} 

View Code

Example 6-13. Logging the error log to a logbook service

 using   System;
  using   System.Collections.Generic;
  using   System.Linq;
  using   System.Text;
  using   System.ServiceModel.Dispatcher;
  using   System.ServiceModel.Channels;
  using   System.ServiceModel;
  using   WCFServiceProgramming.Library;

  namespace   WCFServiceProgramming
{
      class  MyContractClient : ClientBase<IMyContract> , IMyContract
    {
          public   void   DoSomething()
        {
            Channel.DoSomething();
        }
    }

      class   MyErrorHandler : IErrorHandler
    {
          #region  IErrorHandler Members

         public   bool   HandleError(Exception error)
        {
              try  
            {
                MyContractClient proxy  =  new   MyContractClient();

                proxy.DoSomething();
                proxy.Close();
            }
              catch  
            { }
            
              return   false  ;
        }

          public   void  ProvideFault(Exception error, MessageVersion version,  ref   Message fault)
        {
        }

          #endregion  
    }
} 

View Code

Example 6-14. Adding an error extension object

 using   System;
  using   System.Collections.Generic;
  using   System.Linq;
  using   System.Text;
  using   System.ServiceModel;
  using   System.ServiceModel.Channels;
  using   System.Diagnostics;
  using   System.Runtime.Serialization;
  using   System.ServiceModel.Dispatcher;
  using   System.ServiceModel.Description;
  using   System.Collections.ObjectModel;

  namespace   WCFServiceProgramming.Library
{
      class   MyErrorHandler : IErrorHandler
    {
          public   bool   HandleError(Exception error)
        {
              return   false  ;
        }

          public   void  ProvideFault(Exception error, MessageVersion version,  ref   Message fault)
        {
        }
    }

      public   interface   IMyContract
    {
        [OperationContract]
          void   DoSomething();
    }

      class   MyService : IMyContract, IServiceBehavior
    {
          #region  IMyContract Members

         public   void   DoSomething()
        {
            
        }

          #endregion 

         #region  IServiceBehavior Members

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

          public   void   ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase host)
        {
            IErrorHandler handler  =  new   MyErrorHandler();
              foreach  (ChannelDispatcher dispatcher  in   host.ChannelDispatchers)
            {
                dispatcher.ErrorHandlers.Add(handler);
            }
        }

          public   void   Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            
        }

          #endregion  
    }
} 

View Code

Example 6-15. Supporting IErrorHandler by the service class

 using   System;
  using   System.Collections.Generic;
  using   System.Linq;
  using   System.Text;
  using   System.ServiceModel;
  using   System.ServiceModel.Channels;
  using   System.Diagnostics;
  using   System.Runtime.Serialization;
  using   System.ServiceModel.Dispatcher;
  using   System.ServiceModel.Description;
  using   System.Collections.ObjectModel;

  namespace   WCFServiceProgramming.Library
{
      class   MyErrorHandler : IErrorHandler
    {
          public   bool   HandleError(Exception error)
        {
              return   false  ;
        }

          public   void  ProvideFault(Exception error, MessageVersion version,  ref   Message fault)
        {
        }
    }

      public   interface   IMyContract
    {
        [OperationContract]
          void   DoSomething();
    }

      class   MyService : IMyContract, IServiceBehavior, IErrorHandler
    {
          #region  IMyContract Members

         public   void   DoSomething()
        {
            
        }

          #endregion 

         #region  IServiceBehavior Members

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

          public   void   ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase host)
        {
              foreach  (ChannelDispatcher dispatcher  in   host.ChannelDispatchers)
            {
                dispatcher.ErrorHandlers.Add(  this  );
            }
        }

          public   void   Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            
        }

          #endregion 

         #region  IErrorHandler Members

         public   bool   HandleError(Exception error)
        {
              return   false  ;
        }

          public   void  ProvideFault(Exception error, MessageVersion version,  ref   Message fault)
        {
            
        }

          #endregion  
    }
} 

View Code

Example 6-16. The ErrorHandlerBehavior attribute

 using   System;
  using   System.Collections.Generic;
  using   System.Linq;
  using   System.Text;
  using   System.ServiceModel.Description;
  using   System.ServiceModel.Dispatcher;
  using   System.ServiceModel;
  using   System.Collections.ObjectModel;
  using   System.ServiceModel.Channels;

  namespace   WCFServiceProgramming.Library
{
      public   class   ErrorHandlerBehaviorAttribute : Attribute, IServiceBehavior, IErrorHandler
    {
          protected   Type ServiceType
        {
              get  ;
              set  ;
        }

          #region  IServiceBehavior Members

         public   void   AddBindingParameters(ServiceDescription description, ServiceHostBase host, 
            Collection <ServiceEndpoint>  endpoints, BindingParameterCollection bindingParameters)
        {
            
        }

          public   void   ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase host)
        {
            ServiceType  =  description.ServiceType;

              foreach  (ChannelDispatcher dispatcher  in   host.ChannelDispatchers)
            {
                dispatcher.ErrorHandlers.Add(  this  );
            }
        }

          public   void   Validate(ServiceDescription description, ServiceHostBase host)
        {
            
        }

          #endregion 

         #region  IErrorHandler Members

         public   bool   HandleError(Exception error)
        {
              return   false  ;
        }

          public   void  ProvideFault(Exception error, System.ServiceModel.Channels.MessageVersion version,  ref   System.ServiceModel.Channels.Message fault)
        {
            
        }

          #endregion  
    }
} 

View Code

Example 6-17. Implementing AddErrorHandler( )

 using   System;
  using   System.Collections.Generic;
  using   System.Linq;
  using   System.Text;
  using   System.ServiceModel;
  using   System.ServiceModel.Description;
  using   System.Diagnostics;
  using   System.ServiceModel.Channels;
  using   System.ServiceModel.Dispatcher;
  using   System.Collections.ObjectModel;
  using   WCFServiceProgramming.Library;

  namespace   WCFServiceProgramming.Host
{
      public   class  ServiceHost<T>  : ServiceHost
    {
          class   ErrorHandlerBehavior : IServiceBehavior, IErrorHandler
        {
            IErrorHandler m_ErrorHandler;

              public   ErrorHandlerBehavior(IErrorHandler errorHandler)
            {
                m_ErrorHandler  =  errorHandler;
            }

              #region  IErrorHandler Members

             public   bool   HandleError(Exception error)
            {
                  return   false  ;
            }

              public   void  ProvideFault(Exception error, MessageVersion version,  ref   Message fault)
            {  
            }

              #endregion 

             #region  IServiceBehavior Members

             public   void   AddBindingParameters(ServiceDescription description, ServiceHostBase host, 
                Collection <ServiceEndpoint>  endpoints, BindingParameterCollection bindingParameters)
            {
            }

              public   void   ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase host)
            {
                  foreach  (ChannelDispatcher dispatcher  in   host.ChannelDispatchers)
                {
                    dispatcher.ErrorHandlers.Add(  this  );
                }
            }

              public   void   Validate(ServiceDescription description, ServiceHostBase host)
            {
            }

              #endregion  
        }

        List <IServiceBehavior> m_ErrorHandlers =  new  List<IServiceBehavior> ();

          public   void   AddErrorHandler(IErrorHandler errorHandler)
        {
              if  (State ==  CommunicationState.Opened)
            {
                  throw   new  InvalidOperationException( "  Host is already opened  "  );
            }

            IServiceBehavior errorHandlerBehavior  =  new   ErrorHandlerBehavior(errorHandler);
            m_ErrorHandlers.Add(errorHandlerBehavior);
        }

          public   void   AddErrorHandler()
        {
              if  (State ==  CommunicationState.Opened)
            {
                  throw   new  InvalidOperationException( "  Host is already opened  "  );
            }

            IServiceBehavior errorHandlerBehavior  =  new   ErrorHandlerBehaviorAttribute();
            m_ErrorHandlers.Add(errorHandlerBehavior);
        }

          protected   override   void   OnOpening()
        {
              foreach  (IServiceBehavior behavior  in   m_ErrorHandlers)
            {
                Description.Behaviors.Add(behavior);
            }
              base  .OnOpening();
        }
          //  Rest of the implementation 
     }
} 

View Code

Example 6-18. Implementing IEndpointBehavior

 using   System;
  using   System.Collections.Generic;
  using   System.Linq;
  using   System.Text;
  using   WCFServiceProgramming.Library;
  using   System.ServiceModel;
  using   System.ServiceModel.Description;
  using   System.ServiceModel.Dispatcher;
  using   System.ServiceModel.Channels;

  namespace   WCFServiceProgramming
{
      class   MyClient : IMyContractCallback, IEndpointBehavior
    {
          #region  IMyContractCallback Members

         public   void   OnCallback()
        {
        }

          #endregion 

         #region  IEndpointBehavior Members

         public   void   AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection parameters)
        {
        }

          public   void   ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime behavior)
        {
            IErrorHandler handler  =  new   MyErrorHandler();

            behavior.CallbackDispatchRuntime.ChannelDispatcher.ErrorHandlers.Add(handler);
        }

          public   void   ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher dispatcher)
        {
        }

          public   void   Validate(ServiceEndpoint endpoint)
        {
        }

          #endregion  
    }
} 

View Code

Example 6-19. Implementing CallbackErrorHandlerBehavior attribute

 using   System;
  using   System.Collections.Generic;
  using   System.Linq;
  using   System.Text;
  using   System.ServiceModel.Description;
  using   System.ServiceModel.Channels;
  using   System.ServiceModel.Dispatcher;

  namespace   WCFServiceProgramming.Library
{
      public   class   CallbackErrorHandlerBehaviorAttribute : 
        ErrorHandlerBehaviorAttribute, IEndpointBehavior
    {
          public   CallbackErrorHandlerBehaviorAttribute(Type clientType)
        {
            ServiceType  =  clientType;
        }

          #region  IEndpointBehavior Members

         public   void   AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection parameters)
        {
        }

          public   void   ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime behavior)
        {
            behavior.CallbackDispatchRuntime.ChannelDispatcher.ErrorHandlers.Add(  this  );
        }

          public   void   ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher dispatcher)
        {
        }

          public   void   Validate(ServiceEndpoint endpoint)
        {
        }

          #endregion  
    }
} 

View Code

查看更多关于WCF服务编程读书笔记(6):错误的详细内容...

  阅读:37次