Wednesday, March 23, 2011

Silverlight - WCF Exception Handling

We cannot handle WCF exception handling(using Fault Exception) in Silverlight in routine way. I mean when you pass fault exception to client silverlight applcation it does not get exception details through fault contract. For this we have to change HttpStatusCode from 500 to 200[OK].

Follow below stuff to get it done

<DataContract()> _
Public Class MYFaultException

Private _reason As String
Private _code As String

<DataMember()> _
Public Property Reason() As String
Get
Return _reason
End Get
Set(ByVal value As String)
_reason = value
End Set
End Property
<DataMember()> _
Public Property Code() As String
Get
Return _code
End Get
Set(ByVal value As String)
_code = value
End Set
End Property

End Class


Public Class SilverlightFaultBehavior
Inherits BehaviorExtensionElement
Implements IEndpointBehavior


'Public Sub ApplyDispatchBehavior(ByVal endpoint As ServiceEndpoint, ByVal endpointDispatcher As EndpointDispatcher)
' Dim inspector As New SilverlightFaultMessageInspector()
' endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector)
'End Sub

Public Class SilverlightFaultMessageInspector
Implements IDispatchMessageInspector


Public Sub BeforeSendReply(ByRef reply As Message, ByVal correlationState As Object) Implements System.ServiceModel.Dispatcher.IDispatchMessageInspector.BeforeSendReply
If reply.IsFault Then
Dim [property] As New HttpResponseMessageProperty()

' Here the response code is changed to 200.
[property].StatusCode = System.Net.HttpStatusCode.OK


reply.Properties(HttpResponseMessageProperty.Name) = [property]
End If
End Sub




Public Function AfterReceiveRequest(ByRef request As System.ServiceModel.Channels.Message, ByVal channel As System.ServiceModel.IClientChannel, ByVal instanceContext As System.ServiceModel.InstanceContext) As Object Implements System.ServiceModel.Dispatcher.IDispatchMessageInspector.AfterReceiveRequest
Return Nothing
End Function


End Class

' The following methods are stubs and not relevant.

Public Overrides ReadOnly Property BehaviorType() As System.Type
Get
Return GetType(SilverlightFaultBehavior)
End Get
End Property

Protected Overrides Function CreateBehavior() As Object
Return New SilverlightFaultBehavior()
End Function

Public Sub AddBindingParameters(ByVal endpoint As System.ServiceModel.Description.ServiceEndpoint, ByVal bindingParameters As System.ServiceModel.Channels.BindingParameterCollection) Implements System.ServiceModel.Description.IEndpointBehavior.AddBindingParameters

End Sub

Public Sub ApplyClientBehavior(ByVal endpoint As System.ServiceModel.Description.ServiceEndpoint, ByVal clientRuntime As System.ServiceModel.Dispatcher.ClientRuntime) Implements System.ServiceModel.Description.IEndpointBehavior.ApplyClientBehavior

End Sub

Public Sub ApplyDispatchBehavior(ByVal endpoint As System.ServiceModel.Description.ServiceEndpoint, ByVal endpointDispatcher As System.ServiceModel.Dispatcher.EndpointDispatcher) Implements System.ServiceModel.Description.IEndpointBehavior.ApplyDispatchBehavior
Dim inspector As New SilverlightFaultMessageInspector()
endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector)
End Sub

Public Sub Validate(ByVal endpoint As System.ServiceModel.Description.ServiceEndpoint) Implements System.ServiceModel.Description.IEndpointBehavior.Validate

End Sub
End Class

-----------------------------START SERVICE CONTRACT---------------------------

<ServiceContract()> _
Public Interface IService1

<OperationContract()> _
<FaultContract(GetType(MYFaultException))> _
Function GetData(ByVal value As Integer) As String

<OperationContract()> _
Function GetDataUsingDataContract(ByVal composite As CompositeType) As CompositeType

' TODO: Add your service operations here

End Interface

-----------------------------END SERVICE CONTRACT---------------------------

-----------------------------WEB CONFIG SETTINGS ---------------------------
<system.serviceModel>
<extensions>
<behaviorExtensions>
<add name="silverlightFaults"
type="WcfService1.SilverlightFaultBehavior, WcfService1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</behaviorExtensions>
</extensions>
<behaviors>
<endpointBehaviors>
<behavior name="SilverlightFaultBehavior">
<silverlightFaults/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>

<behavior name="SilverlightFaultBehavior">

<serviceDebug includeExceptionDetailInFaults="true"/>

<serviceMetadata httpGetEnabled="true"/>

</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="WcfService1.Service1" behaviorConfiguration="SilverlightFaultBehavior">
<endpoint address=""
binding="basicHttpBinding"
contract="WcfService1.IService1"
behaviorConfiguration="SilverlightFaultBehavior" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>

-----------------------------END WEB CONFIG SETTINGS ---------------------------

-----------------------------IN SILVERLIGHT APP ---------------------------

Private Sub serProxy_GetData(ByVal sender As Object, ByVal e As ServiceReference1.GetDataCompletedEventArgs)
If e.Error Is Nothing Then
txtErrorMessage.Text = e.Result
Else
txtErrorMessage.Text = e.Error.Message
End If
End Sub
-----------------------------END IN SILVERLIGHT APP ---------------------------

No comments: