• 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
  • 相关阅读:
    ng的ngModel用来处理表单操作
    ionic改tab文字和icon图片的颜色
    ionic安装遇到的一些问题
    ionic运行测试
    安卓sdk安装教程
    ionic教程
    ng 构建
    ng websocket
    ng依赖注入
    Python: 定时器(Timer)简单实现
  • 原文地址:https://www.cnblogs.com/thlzhf/p/2782999.html
Copyright © 2020-2023  润新知