Service Exception Handling and Channel Fault handling at client side in WCF

Objective 

In this article, I will show different approach to deal with service side exception and channel fault at client side. I will do a comparison study between various approaches and I will provide best approach also.

Service 

Consider the below very simple Contract and Service

IService1

using System;

using System.Collections.Generic;

using System.Linq;

using System.Runtime.Serialization;

using System.ServiceModel;

using System.Text;

namespace FaultSample1

{

[ServiceContract]


public
interface
IService1

{

[OperationContract]


string GetData();

}

}

Service1

using System;

using System.Collections.Generic;

using System.Linq;

using System.Runtime.Serialization;

using System.ServiceModel;

using System.Text;

namespace FaultSample1

{


public
class
Service1 : IService1

{


public
string GetData()

{


return
“Hello WCF”;

}

}

}

Three Facts about Channel Faulting is 

  1. If there is transport session, Client cannot even close the Proxy.
  2. If there is no transport session, technically client could continue to using Proxy after a Service exception.
  3. Client could only Abort the proxy in case of exception.

Now at client side, 

Approach # 1 (Simple Approach)

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using ConsoleApplication1.ServiceReference1;

namespace ConsoleApplication1

{


class
Program

{


static
void Main(string[] args)

{


Service1Client Proxy = new
Service1Client();


try

{


string result= Proxy.GetData();


Console.WriteLine(result);

}


catch

{

}


string resultafterexception =Proxy.GetData();


Console.WriteLine(resultafterexception);


Console.ReadKey(true);

}

}

}

If there is no transport session, technically client could continue using the Proxy even after Channel is faulted. So in above approach client may continue using faulted channel and that is not good.

 Approach # 2 (Calling Abort)
The other thing client could do to prevent using Proxy for a faulted channel is to call Abort.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using ConsoleApplication1.ServiceReference1;

namespace ConsoleApplication1

{


class
Program

{


static
void Main(string[] args)

{


Service1Client Proxy = new
Service1Client();


try

{


string res= Proxy.GetData();


Console.WriteLine(res);

}


catch

{

Proxy.Abort();

}


Console.ReadKey(true);

}

}

}

But problem in above approach is that, Proxy is not getting closed. So there is Service Instance , which has not disposed.

Approach # 3 (Closing the Proxy with using statement)

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using ConsoleApplication1.ServiceReference1;

namespace ConsoleApplication1

{


class
Program

{


static
void Main(string[] args)

{


using (Service1Client Proxy = new
Service1Client())

{


try

{


string res= Proxy.GetData();


Console.WriteLine(res);

}


catch

{

Proxy.Abort();

}

}


Console.ReadKey(true);

}

}

}

Problem with relying in using statement to close the proxy is that , if any server side exception is causing channel to get faulted and after that when using statement will try to dispose the proxy , when the channel is faulted will cause CommunicationObjectFaultedException. Code after using statement will never get called.

Approach # 4 using statement in try/catch

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using ConsoleApplication1.ServiceReference1;

namespace ConsoleApplication1

{


class
Program

{


static
void Main(string[] args)

{


try

{


using (Service1Client Proxy = new
Service1Client())

{


try

{


string res = Proxy.GetData();


Console.WriteLine(res);

}


catch

{

Proxy.Abort();

}

}

}


catch

{

}


Console.ReadKey(true);

}

}

}

Readability of this code is not so good. It is very tough to understand many nested try/catch.

Best Approach

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using ConsoleApplication1.ServiceReference1;

namespace ConsoleApplication1

{


class
Program

{


static
void Main(string[] args)

{


Service1Client Proxy=null;


try

{

Proxy = new
Service1Client();


string res = Proxy.GetData();


Console.WriteLine(res);

Proxy.Close();

}


catch

{

Proxy.Abort();

}


Console.ReadKey(true);

}

}

} 

Above approach is closing the Proxy. If channel is faulted then aborting the Proxy. Above code is highly readable also.

Conclusion

In this article, we saw various ways of dealing with Service side Exception and Channel Fault at client side. You could download the attached code for reference. Thanks for reading.

Happy Coding

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s