Learning WCF:Fault Handling


There are two types of Execptions which can be throwed from the WCF service. They are Application excepiton and Infrastructure exception.

Handle Application Exception

If we do nothing, a FaultException always be throwed when your WCF service appear any error. For example:

Service:

using Service.Interface;
using Entities;
using System;

namespace Service
{
    public class PeopleService : IPeopleOperator
    {
        public void DeletePerson(Person person)
        {
            Console.WriteLine("Have deleted a person whoes name is:" + person.Name);
        }
    }
}

Client:

using Entities;
using Service.Interface;
using System;
using System.ServiceModel;


namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            using (ChannelFactory<IPeopleOperator> channelFactory = new ChannelFactory<IPeopleOperator>(new WSHttpBinding(), 
                "http://localhost:9999/PeopleService"))
            {
                IPeopleOperator proxy = channelFactory.CreateChannel();

                Person person = null;
                proxy.DeletePerson(person);

                Console.Read();
            }
        }
    }
}

When you run the Client code:

图片.png-25.7kB

There is no useful information. We should use Fault Contract. Fault Contract allow developer define error information entity flexible.

Using Fault Contract

Create an Error message container entity

using System.Runtime.Serialization;

namespace Entities
{
    [DataContract]
    public class ErrorInformation
    {
        public ErrorInformation(string messages,
            string serviceName,
            string methodName)
        {
            Messages = messages;
            ServiceName = serviceName;
            MethodName = methodName;
        }

        [DataMember]
        public string Messages { get; private set; }

        [DataMember]
        public string ServiceName { get; private set; }

        [DataMember]
        public string MethodName { get; private set; }
    }
}

Apply FaultContract attribute on the operation of the contract interface

using Entities;
using System.ServiceModel;

namespace Service.Interface
{
    [ServiceContract(Name = "PeopleOperatorService", Namespace ="http://zzy0471.cnblogs.com")]
    public interface IPeopleOperator
    {
        [FaultContract(typeof(ErrorInformation))]
        [OperationContract]
        void DeletePerson(Person person);
    }
}

Mondify the Service Code

using Service.Interface;
using Entities;
using System;
using System.ServiceModel;

namespace Service
{
    public class PeopleService : IPeopleOperator
    {
        
        public void DeletePerson(Person person)
        {
            if (person == null)
            {
                var error = new ErrorInformation("参数person为null",
                    "PeopleService",
                    "DeletePerson");

                throw new FaultException<ErrorInformation>(error);
            }
            else
            {
                Console.WriteLine("Have deleted a person whoes name is:" + person.Name);
            }
        }
    }
}

Mondify the Clinet Code:

using Entities;
using Service.Interface;
using System;
using System.ServiceModel;

namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            using (ChannelFactory<IPeopleOperator> channelFactory = new ChannelFactory<IPeopleOperator>(new WSHttpBinding(), 
                "http://localhost:9999/PeopleService"))
            {
                IPeopleOperator proxy = channelFactory.CreateChannel();

                Person person = null;
                try
                {
                    proxy.DeletePerson(person);
                }
                catch (FaultException<ErrorInformation> fe)
                {
                    Console.WriteLine(fe.Detail.Messages + " in method " + fe.Detail.MethodName + " of service " + fe.Detail.ServiceName);
                }
                catch(FaultException)
                {
                    Console.WriteLine("Unknow FaultException");
                }

                Console.Read();
            }
        }
    }
}

Handle Infrastructure Exception

Except application exceptions, some Infrastructure Exceptions occasionally occur. For example: communication error, which may occur because of network unavailability, an incorrect address, the host process not running, and so on. The second type of error is related to the state of the proxy
and the channels. So We need some more catch:

catch (CommunicationException ex)
{
    Console.WriteLine("Communication error:" + ex.Message);
}
catch(ObjectDisposedException ex)
{
    Console.WriteLine("The proxy is closed:" + ex.Message);
}
catch (InvalidOperationException ex)
{
    Console.WriteLine("InvalidOperation:" + ex.Message);
}
catch(TimeoutException ex)
{
    Console.WriteLine("Timeout:" + ex.Message);
}
catch(Exception)
{
    Console.WriteLine("Unknow Infrastructure Exception ");
}

Whole code of client:

using Entities;
using Service.Interface;
using System;
using System.ServiceModel;

namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            using (ChannelFactory<IPeopleOperator> channelFactory = new ChannelFactory<IPeopleOperator>(new WSHttpBinding(), 
                "http://localhost:9999/PeopleService"))
            {
                IPeopleOperator proxy = channelFactory.CreateChannel();

                Person person = null;
                try
                {
                    proxy.DeletePerson(person);
                }

                //
                // Application Exception 
                //
                catch (FaultException<ErrorInformation> fe)
                {
                    Console.WriteLine(fe.Detail.Messages + " in method " + fe.Detail.MethodName + " of service " + fe.Detail.ServiceName);
                }
                catch(FaultException)
                {
                    Console.WriteLine("Unknow Application FaultException");
                }

                //
                // Infrastructure Exception 
                //
                catch (CommunicationException ex)
                {
                    Console.WriteLine("Communication error:" + ex.Message);
                }
                catch(ObjectDisposedException ex)
                {
                    Console.WriteLine("The proxy is closed:" + ex.Message);
                }
                catch (InvalidOperationException ex)
                {
                    Console.WriteLine("InvalidOperation:" + ex.Message);
                }
                catch(TimeoutException ex)
                {
                    Console.WriteLine("Timeout:" + ex.Message);
                }
                catch(Exception)
                {
                    Console.WriteLine("Unknow Infrastructure Exception ");
                }
                Console.Read();
            }
        }
    }
}

That's all.

Download the sourcecode

posted @   会长  阅读(483)  评论(5编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示