<

Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x

Propagating Fault Exception to Silverlight Client

Published on
10,140 Points
4,140 Views
Last Modified:
While working on Silverlight and WCF application, I faced one issue where fault exception occurred at WCF operation contract is not getting propagated to Silverlight client. So after searching net I came to know that it was behavior by default for silverlight client. And these issues can be addressed by little tweak. So, here I am writing on how to propagate fault exception from service to silverlight client.

Reason for this kind of behavior is if any fault exception is raised at operation contract, then the exception is converted to SOAP faults and returned to the client. Since the networking in Silverlight is performed based on browser's HTTP stack. But this limitation is applicable to Silverlight 2. In Silverlight 3, the networking is performed using browser HTTP stack by default. But the new client HTTP stack allows you to bypass the browser and perform networking operation through operating system.

In Silverlight 2, SOAP faults cannot be propagated to client side because due to limitations in silverlight, it cannot access some of the messages in the browser HTTP stack bodies. So HTTP error code 500 which holds the SOAP faults is converted to 404(Page not found), and same is returned to client. So obviously client will be receiving "Remote Server not found"  exception.

In Silverlight 3, this limitation is solved. Since Silverlight 3 uses client HTTP stack, it is simple that networking is performed by API's exposed by operating system itself. So you can tell Silverlight to use the client HTTP stack for requests made, instead of using browser HTTP stack. Below is the code use to inform the silverlight to use client http stack for requests call made for sites begin with http://.
HttpWebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp);

Open in new window


Adding the above line code will make all subsequent call starts with http:// to client HTTP stack.

To support for specific site then add the below code
HttpWebRequest.RegisterPrefix("http://xxxx.com", WebRequestCreator.ClientHttp);

Open in new window



Ok, here another question kicked off my mind. What if my Silverlight client is creating web request to WCF service via proxies created at my client side and Silverlight is intended to receive SOAP faults regardless of the address. So do I need to extend my WCF behaviors, so that WCF service will be intelligent enough to convert the http error codes before sending back to client? The answer is YES. Here I will explain on how to achieve this.

My Service Contract and Operation Contract is defined as shown below

 [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        [FaultContract(typeof(ValidationException))]
        string getData();
    }

Open in new window


Data contract class which define data member with some validation rules. StringLength validator is available in System.ComponentModel.DataAnnotations.

 [DataContract]
    public class MyDataContract
    {
        [DataMember]
        [StringLength(10, ErrorMessage="String length should not be greater than 10")]
        public string Name { get; set; }
    }

Open in new window


Contracts implemented in Service class

public class Service1 : IService1
    {
        
        public string getData()
        {
            MyDataContract dc = new MyDataContract();
            dc.Name = "12345678901"; // string length greater than 10
            return dc.Name;
        }
    }

Open in new window


here getData() method throws FaultException of type ValidationException, which inturn converted to SOAP fault. So in order to propagate the SOAP fault to silverlight client we need to extend the endpoint behavior so that SOAP faults can be sent to silverlight client. Below are the steps:

1.) Create a class which is inherited from System.ServiceModel.Configuration.BehaviorExtensionElement and also implemets System.ServiceModel.Description.IEndpointBehavior.

 public class SilverlightFaultContractBehavior : BehaviorExtensionElement, IEndpointBehavior

    {
        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
            SilverlightFaultMessageInspector faultnspector = new SilverlightFaultMessageInspector();
            endpointDispatcher.DispatchRuntime.MessageInspectors.Add(faultnspector);
        }

        public class SilverlightFaultMessageInspector : IDispatchMessageInspector
        {

            public void BeforeSendReply(ref Message reply, object correlationState)
            {
                if (reply.IsFault)
                {
                    HttpResponseMessageProperty property = new HttpResponseMessageProperty();

                    // Here the response code is changed to 200.
                    property.StatusCode = System.Net.HttpStatusCode.OK;


                    reply.Properties[HttpResponseMessageProperty.Name] = property;
                }
            }

            public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
            {
                // Dont do anything to incoming request. 
                return null;
            }


        }

        // The following methods are not relevant. So doing dummy implementation of  IEndpointBehavior interface

        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
        }


        public void Validate(ServiceEndpoint endpoint)
        {
        }

        public override System.Type BehaviorType
        {
            get { return typeof(SilverlightFaultContractBehavior); }
        }

        protected override object CreateBehavior()
        {
            return new SilverlightFaultContractBehavior();
        }

    }

Open in new window


2.) Do the appropriate changes to web.config file.

<system.serviceModel>
      <extensions>
        <behaviorExtensions>
          <add name="silverlightFaults"
               type="SilverlightApplication1.Lib.SilverlightFaultContractBehavior, 
             SilverlightFaultContractBehavior, 
             Version=1.0.0.0, 
             Culture=neutral, 
             PublicKeyToken=null"/>
        </behaviorExtensions>
      </extensions>

      <behaviors>
        <endpointBehaviors>
          <behavior name="SilverlightFaultBehavior">
            <silverlightFaults/>
          </behavior>
        </endpointBehaviors>

        <serviceBehaviors>
                <behavior name="">
                    <serviceMetadata httpGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="false" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
     
      <services>
        <service name="SilverlightApplication1.Web.Service1">
          <endpoint address=""
                    binding="basicHttpBinding"
                    contract="SilverlightApplication1.Web.IService1"
                    behaviorConfiguration="SilverlightFaultBehavior" />
        </service>
      </services>

      <serviceHostingEnvironment aspNetCompatibilityEnabled="True" multipleSiteBindingsEnabled="true" />
    </system.serviceModel>

Open in new window


3.) Client code:
 SilverlightApplication1.ServiceReference1.Service1Client client = new SilverlightApplication1.ServiceReference1.Service1Client();
            client.getDataCompleted += new EventHandler<getDataCompletedEventArgs>(client_getDataCompleted);
            client.getDataAsync();

 void client_getDataCompleted(object sender, getDataCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                if (e.Error is FaultException)
                {
                    MessageBox.Show(e.Error.Message);
                }
            }
        }

Open in new window


This is how you can propagate Fault Exceptions to Silverlight Client.

Any feedback and suggestions is highly recommended!!!!!!!!

Thanks......
0
Comment
Author:Sathish DV
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
0 Comments

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Join & Write a Comment

Visualize your data even better in Access queries. Given a date and a value, this lesson shows how to compare that value with the previous value, calculate the difference, and display a circle if the value is the same, an up triangle if it increased…
In this video, Percona Solutions Engineer Barrett Chambers discusses some of the basic syntax differences between MySQL and MongoDB. To learn more check out our webinar on MongoDB administration for MySQL DBA: https://www.percona.com/resources/we…
Other articles by this author

Keep in touch with Experts Exchange

Tech news and trends delivered to your inbox every month