ARTICLE

Exception Handling in Silverlight Application From WCF in VB.NET

Posted by Saravana Kumar Articles | Visual Basic .NET November 08, 2012
This article explains exception handling in a Silverlight application from WCF.
Reader Level:
 

Introduction:

This article explains exception handling in a Silverlight application from WCF. I have created the sample Silverlight application, which uses the WCF service to process the data. While testing the application I encoutered the exception message thrown from WCF that it cannot be received at the client side (Silverlight application) even after using the FaultException. I was always getting System.ServiceModel.CommunicationException: The remote server returned an error: NotFound.

remote-server.gif
 
 
Later I learned that WCF throws a HTTP 500 series fault message but Silverlight can handle only the 200 series. So we need to convert the 500 series to a 200 error message for Silverlight. Here is the sample application for exception handling between WCF and Silverlight.
 
Step 1:

We can customize the Endpoint behavior of the WCF service by inheriting the BehaviorExtensionElement and implementing the IEndpointBehavior. The actual code for converting the 500 error series to 200 series is in the BeforeSendReply method.

Create a ClassLibrary project and name it "Silverlight_WCF_FaultBehavior" and name the class "SilverlightFaultBehavior". Copy and paste the following code inside the SilverlightFaultBehavior class.

 
Imports System.ServiceModel.Configuration
Imports System.ServiceModel.Description
Imports System.ServiceModel.Dispatcher
Imports System.ServiceModel.Channels
Imports System.ServiceModel

 
    PublicClass SilverlightFaultBehavior
        Inherits BehaviorExtensionElement
        Implements IEndpointBehavior
        PublicOverrides ReadOnly Property BehaviorType()As System.Type
            Get
                ReturnGetType(SilverlightFaultBehavior)
            EndGet
        EndProperty
        ProtectedOverrides Function CreateBehavior() AsObject
            ReturnNew SilverlightFaultBehavior
        EndFunction
        PublicSub AddBindingParameters(ByVal endpoint As System.ServiceModel.Description.ServiceEndpoint,ByVal bindingParametersAs System.ServiceModel.Channels.BindingParameterCollection)Implements System.ServiceModel.Description.IEndpointBehavior.AddBindingParameters
        EndSub
        PublicSub ApplyClientBehavior(ByVal endpoint As System.ServiceModel.Description.ServiceEndpoint,ByVal clientRuntimeAs System.ServiceModel.Dispatcher.ClientRuntime) Implements System.ServiceModel.Description.IEndpointBehavior.ApplyClientBehavior
        EndSub
        PublicSub ApplyDispatchBehavior(ByVal endpoint As System.ServiceModel.Description.ServiceEndpoint,ByVal endpointDispatcherAs System.ServiceModel.Dispatcher.EndpointDispatcher)Implements System.ServiceModel.Description.IEndpointBehavior.ApplyDispatchBehavior
            Dim inspector AsNew SilverlightFaultMessageInspector()
            endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector)
        EndSub
        PublicSub Validate(ByVal endpoint As System.ServiceModel.Description.ServiceEndpoint)Implementsystem.ServiceModel.Description.IEndpointBehavior.Validate
        EndSub
        PublicClass SilverlightFaultMessageInspector
            Implements IDispatchMessageInspector
            PublicFunction AfterReceiveRequest(ByRef request As System.ServiceModel.Channels.Message, ByVal channel As System.ServiceModel.IClientChannel, ByVal instanceContext As System.ServiceModel.InstanceContext) AsObject Implements System.ServiceModel.Dispatcher.IDispatchMessageInspector.AfterReceiveRequest
                ' Do nothing to the incoming message.
                ReturnNothing
            EndFunction
            PublicSub BeforeSendReply(ByRef reply As System.ServiceModel.Channels.Message, ByVal correlationState AsObject) Implements System.ServiceModel.Dispatcher.IDispatchMessageInspector.BeforeSendReply
                If reply.IsFault Then
                    Dim [property] AsNew HttpResponseMessageProperty() 
                    ' Here the response code is changed to 200.
                    [property].StatusCode = System.Net.HttpStatusCode.OK
                    reply.Properties(HttpResponseMessageProperty.Name) = [property]
                EndIf
            EndSub
        EndClass
    EndClass

 
Note: The highlighted code shows the conversion from the 500 series to 200 series error code.
 
Step 2

Build the project.

 
Step 3: 
 
Create a new WCF service with Interface and implementation class as follows:
 
Interface
 
<ServiceContract()> _
PublicInterface IService
    <OperationContract()> _
    Function Add(ByVal num1 As Integer, ByVal num2As Integer)As Integer
    <OperationContract()> _
    Function Subtract(ByVal num1As Integer,ByVal num2 As Integer)As Integer  
EndInterface
 
Implementation 
 
PublicClass Service
    Implements IService
    PublicSub New()
    EndSub
    PublicFunction Add(ByVal num1 As Integer, ByVal num2As Integer)As IntegerImplements IService.Add
        ThrowNew FaultException("Error thrown by user for Add operation")
        'Return num1 + num2
    EndFunction
    PublicFunction Subtract(ByVal num1 As Integer, ByVal num2As Integer)As IntegerImplements IService.Subtract
        Return num1 - num2
    EndFunction
EndClass
 
Step 4:
 
Add the Silverlight_WCF_FaultBehavior project dll as a reference to the WCF Service.
 
Step 5:
 
In WCF we can extend the binding and behavior by using the <extention> tag. In our case we are also extending the custom endpoint behavior as shown below. In the <behaviorExtensions> tag we need to specify the fully qualified name of the custom behavior assembly.
 
Modify the Web.config file as shown below:
 
<system.serviceModel>
    <services>
      <servicename="Service"behaviorConfiguration="ServiceBehavior">
        <!-- Service Endpoints -->
        <endpointaddress=""binding="basicHttpBinding"contract="IService"behaviorConfiguration="SilverlightFaultBehavior">
          <!--
              Upon deployment, the following identity element should be removed or replaced to reflect the
              identity under which the deployed service runs.  If removed, WCF will infer an appropriate identity
              automatically.
          -->
          <identity>
            <dnsvalue="localhost"/>
          </identity>
        </endpoint>
        <endpointaddress="mex"binding="mexHttpBinding"contract="IMetadataExchange"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behaviorname="ServiceBehavior">
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadatahttpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebugincludeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behaviorname="SilverlightFaultBehavior">
          <silverlightFaults/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <extensions>
      <behaviorExtensions>
        <addname="silverlightFaults"type="Silverlight_WCF_FaultBehavior.SilverlightFaultBehavior, Silverlight_WCF_FaultBehavior, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null"/>
      </behaviorExtensions>
    </extensions>
  </system.serviceModel>

 
Step 6:
 
Create the sample Silverlight application as "Silverlight_WCF_Exception" and add this WCF service as the Service Reference.
 
URL: http://localhost/MathService/Service.svc 
 
Step 7: 
 
Add a button to the MainPage.xaml and call the WCF method as shown below:
 
PrivateSub Button_Click(ByVal sender As System.Object,ByVal e As System.Windows.RoutedEventArgs)
        Dim proxyAs New ServiceProxy.ServiceClient
        AddHandler proxy.AddCompleted, AddressOf AddOperationCompleted
        proxy.AddAsync(5, 6)
End Sub
Private Sub AddOperationCompleted(ByVal senderAs Object,ByVal e As ServiceProxy.AddCompletedEventArgs)
        If e.ErrorIsNot Nothing Then
            MessageBox.Show(e.Error.Message)
        Else
            MessageBox.Show(e.Result)
        EndIf
EndSub
 
Step 8:

The output will look like this:

error-thrown-vb.net.gif
 

Conclusion:
 
This article explains about exception handling in a Silverlight application from WCF. I will get back to you guys with another article.

COMMENT USING