重温WCF之WCF抛出异常的处理SOAP Fault(十二)

1.(服务端)抛出和(客户端)捕获SOAP Fault
当我们需要客户端获取到WCF服务端的抛出的异常的时候,使用FaultException类
WCF类库在System.ServiceModel命名空间下提供了FaultException类。如果WCF服务抛出FaultException对象,WCF运行时将生成SOAP fault消息并回传给客户端程序。
服务端抛出异常
catch (Exception ex)
{
    if (ex.InnerException is System.Data.SqlClient.SqlException)
        throw new FaultException(string.Format("Exception accessing database:{0}",
            ex.InnerException.Message), new FaultCode("Connect to database"));
    else
        throw new FaultException(string.Format("Exception reading from numbers: {0}",
            ex.Message), new FaultCode("Iterate through products"));
}

客户端捕获异常
try
{
    ...
}
catch (FaultException ex)
{ 
    Console.WriteLine("{0}: {1}", ex.Code.Name, ex.Reason)
}

2.使用强类型SOAP faults
调用WCF服务时不知道会抛出什么样的异常,使用一个类来约定客户端和服务器端来约定服务器端抛出来的异常
服务器端代码:
    [DataContract]
    public class SystemFault
    {
        [DataMember]
        public string SystemOperation { get; set; }

        [DataMember]
        public string SystemReason { get; set; }

        [DataMember]
        public string SystemMessage { get; set; }
    }

	 [FaultContract(typeof(SystemFault))]
        [OperationContract]
        string GetData(int value);

		public string GetData(int value)
        {
            SystemFault fault = new SystemFault
            {
                SystemOperation = "哪个操作",
                SystemReason = "错误原因",
                SystemMessage ="错误消息"
            };
            throw new FaultException(fault);
            return string.Format("You entered: {0}", value);
        }

客户端代码:
catch (FaultException sf)
 {
        Console.WriteLine("SystemFault {0}: {1}
{2}",
            sf.Detail.SystemOperation,
            sf.Detail.SystemMessage,
            sf.Detail.SystemReason);
 }


3.报告意外预料之外的异常
在你开发WCF服务时,为了在客户端程序调试,将会把服务端发生的所有异常(包括预料之内的和预料之外的)转换成SOAP faults消息传送至客户端是非常有用的。
调试的时候将WCF服务的配置文件 设置为true,等正式上线的时候设置为false

4.在WCF服务宿主处理异常
(1)针对错误处理,ServiceHost则提供了Faulted事件,调用该事件后,ServiceHost对象进入Faulted状态。当发生错误的时候,你通过订阅该事件,然后使用其提供的方法确定发生错误的原因,最后抛弃现有的服务并重启一个新的服务。
示例代码:
try
{
ServiceHost productsServiceHost;
productsServiceHost = new ServiceHost(typeof(Products.ProductsService));
        productsServiceHost.Open();

        // subscribe the faulted event
        productsServiceHost.Faulted += (eventSender, eventArgs) =>
            {
                productsServiceHost.Abort();

                productsServiceHost = new ServiceHost(typeof(Products.ProductsService));
                productsServiceHost.Open();
            };
}
catch (Exception ex)
{
   // handleException(ex);
}

(2)在宿主程序中处理来自客户端的预料之外的消息
客户端发送消息
   Message request = Message.CreateMessage(MessageVersion.Soap11, "http://tempuri.org/IProductsService/ListProducts");
   服务端处理
        productsServiceHost.UnknownMessageReceived +=(eventSendaer, eventArgs)
            {
                MessageBox.Show(string.Format("A client attempted to send the message {0}",
                    eventArgs.Message.Headers.Action));
            };
原文地址:https://www.cnblogs.com/yxlblogs/p/4270808.html