Showing posts with label FaultContract. Show all posts
Showing posts with label FaultContract. Show all posts

Tuesday, February 14, 2012

Handling WCF FaultContract & FaultException in Silverlight

What is FaultContract in WCF and how to handle fault exception in a windows application has been posted 1 year ago in this same blog itself. Some time back we one of colleague was trying to implement the same in his Silverlight application and he was not able to leverage my post to accomplish his task as Silverlight uses async pattern to call the service and the binding is basicHttp. The basicHttpBinding uses the SOAP protocol and it returns the fault using the HTTP 500 series status code which cannot be understood by Silverlight. So we modify the WCF response using custom EndPointBehavior and a MessageInspector to return using HTTP 200 code.

All those details are specified in the MSDN itself. What I am doing here is to post a sample in Silverlight 4.0 :-)
http://msdn.microsoft.com/en-us/library/ee844556(v=vs.95).aspx

No its not just a sample. It describes how to write client side code which is not mentioned in the MSDN article.Mainly where to put try catch to catch the fault exception. For the server side code and configurations just look at the MSDN article. Client side code you can get from below section.


   1:  private void GetChar(String ipString, int position)
   2:  {
   3:          MyServiceReference.MyServiceClient client = new MyServiceReference.MyServiceClient();
   4:          client.GetCharCompleted += (sender, e) =>
   5:          {
   6:              try
   7:              {
   8:                  if (e.Error != null) throw e.Error;
   9:                  MessageBox.Show("Extracted character: " + e.Result.ToString());
  10:              }
  11:              catch (FaultException<MyServiceReference.MyException> ex)
  12:              {
  13:                  MessageBox.Show("FaultException occurred " + ex.Detail.ExMessage);
  14:              }
  15:              catch (FaultException ex)
  16:              {
  17:                  MessageBox.Show(ex.Message);
  18:              }
  19:          };
  20:          client.GetCharAsync(ipString, position);
  21:  }

The main difference is the position of try catch blocks .In the sync service calls it will be wrapping the service call itself.Here we have 2 ways as the exception comes through the e.Error property.Either we can check the type in the handler itself or throw to handle by the callers.

Saturday, June 12, 2010

Using FaultContract in WCF to handle exceptions

FaultContract is the word which came with WCF.As its name states it is for handling the faults.But how can we handle the fault? In this post I am just going to describe about implementing the FaultContract and its handling at client side.

What is FaultContract

It is just an attribute which is used to decorate the service method which is already marked as OperationContract.This tells that the method may throw the Fault using the specified generic class.Oh.What is this generic class? Just look at the code.

<ServiceContract()> _
Public Interface IMyService
<OperationContract()> _
<FaultContract(GetType(MyException))> _
Function GetChar(ByVal data As String, ByVal position As Integer) As Char


MyException is the generic class which I mentioned.Its just a class used to transmit the custom details about the fault to the client.

<DataContract()> _
Public Class MyException
Dim m_Message As String = String.Empty
<DataMember()> _
Public Property ExMessage() As String
Get
Return m_Message
End Get
Set(ByVal value As String)
m_Message = value
End Set
End Property

Public Sub New()
End Sub
Public Sub New(ByVal message As String)
MyBase.New()
m_Message = message
End Sub
End Class


Dont forget to mark this class as DataContract.This class is normally known as ExceptionDetail or detailType in other sites and tutorials.
Invoking the Fault

In your service implementation you can have the try catch blocks and from the catch you can throw the FaultException.It will reach up to client and client can handle that.Also you can throw the Fault from  anywhere in your code.

Public Function GetChar(ByVal data As String, ByVal position As Integer) As Char Implements IMyService.GetChar
Try
Return data(position)
Catch aEx As IndexOutOfRangeException
Dim a As MyException = New MyException(aEx.Message)
Throw New FaultException(Of MyException)(a)
Catch aEx As Exception
Dim a As MyException = New MyException(aEx.Message)
Throw New FaultException(Of MyException)(a)
End Try
End Function


Even if you didn’t handle the exception it will reach to client if your web.config is proper.ie ServiceBehaviour is as follows

<behavior name="WcfService2.Service1Behavior" returnUnknownExceptionsAsFaults="True">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>


Server side
Lets see what are all the things we need to do at the server side.

  1. Create the  class to transmit the exception details.


  2. Mark the service methods with FaultContract attribute by passing the detail class.


  3. Change your web.config to set includeExceptionDetails to true.


  4. Throw the FaultException from your service implementation from where ever required.


Client side

  1. Add the service reference.

  2. Wrap the service call with try catch and handle the FaultException.

    Private Sub GetChar(ByVal no1 As String, ByVal no2 As Double)
    Try
    Dim service As New ServiceReference1.MyServiceClient
    MessageBox.Show(service.GetChar(no1, no2))
    Catch ex As FaultException(Of FaultContractTest.Core.MyException)
    MessageBox.Show(ex.Detail.ExMessage)
    Catch ex As FaultException
    MessageBox.Show(ex.Message)
    Catch ex As Exception
    MessageBox.Show(ex.Message)
    End Try
    End Sub




You can download a sample from my sky drive which implements the above.