Sony Arouje

a programmer's log

Proxy less Silverlight – WCF Async communication

with 12 comments

In this post I am going to explain how a silverlight application can communicate with WCF service without any proxy. I wanted to establish this communication without any autogenerated code because am not a fan of proxies generated by VS. If you want VS to create good autogenerated code then probably invest some time in learning T4 templates. Anyway I haven’t done any research in T4 templates, so let’s do every thing by hand.

Here is my requirement, I have to show a list of customer in my Silverlight app. Keep in mind it just an experiment, so no db involved in this app. For simplicity I hosted my wcf service in IIS.

Let’s straight to the code.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using DataModel;
namespace ServiceContracts
{
    [ServiceContract]
    public interface ICustomerService
    {
        [OperationContract]
        ICollection<Customer> GetCustomerList();
    }

}

I only have one function in the service contract, a function return a collection of Customer class. Customer class is a just a C# class that has only two properties as shown below

using System.Runtime.Serialization;
namespace DataModel
{
    [DataContract]
    public class Customer
    {
        [DataMember]
        public int CustomerId { get; set; }

        [DataMember]
        public string CustomerName { get; set; }
    }
}
Let’s give some implementation to our Service Contract
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ServiceContracts; //assembly consist service contracts
using DataModel; //assembly contains data contracts
namespace ServiceLayer
{
    public class CustomerService:ICustomerService
    {
        public ICollection<Customer> GetCustomerList()
        {
            List<Customer> customers = new List<Customer>();
            Customer cust = new Customer();
            cust.CustomerId = 1;
            cust.CustomerName = "sony";

            customers.Add(cust);
            return customers;
        }

        }

}

 

Now our service is ready to host, here I use IIS to host it. But how does Silverlight can utilize the Function we implemented, because I haven’t implemented Async methods. You might know that Silverlight can only work in Async mode. There are several ways of calling the above implemented service in Silverlight. One way is adding Service reference and leave it to VS to create the proxy with Async code generation. Another approach is use Castle Windsor to host the service in Async mode. Some how I didn’t like both the approach so I was trying for a better approach. My search ended up in a blog to achieve the Async communication without much modification to my Service code.

Here is the approach I was looking at. Create a new Service contract with Async functions and make it an alias to my original ICustomerSerivce

[ServiceContract(Name = "ICustomerService")]
public interface ICustomerServiceAsync
{
    [OperationContract(AsyncPattern = true)]
    IAsyncResult BeginGetCustomerList(AsyncCallback callback, object state);

    ICollection<Customer> EndGetCustomerList(IAsyncResult result);
}

 

And use the above ICustomerServiceAsync to communicate to ICustomerService. This approach is pretty clean and we don’t want to add any Async methodology to our core service.

Below is my web.config of WCFService host.

<?xml version="1.0"?>
<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="CustomerService">
        <endpoint address="" contract="ServiceContracts.ICustomerService" binding="basicHttpBinding"></endpoint>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="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 -->
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>  
</configuration>

 

As you see my service end point configuration I have not mentioned ICustomerServiceAsync. Let’s go through the silverlight client how we can communicate to our service.

private void button1_Click(object sender, RoutedEventArgs e)
{
    EndpointAddress endPoint = new EndpointAddress("http://localhost:63301/CustomerService.svc");
    BasicHttpBinding binding = new BasicHttpBinding();
    ICustomerServiceAsync customerService = new ChannelFactory<ICustomerServiceAsync>(binding, endPoint).CreateChannel();

    customerService.BeginGetCustomerList(a => 
    {
        try
        {
            ICollection<Customer> person = customerService.EndGetCustomerList(a);
        }
        catch (Exception ex)
        {
            throw ex;
        }

    }, customerService);

}

In a button click am calling the service.  Here I used the ICustomerAsync to create the channel. Ayende’s blog will give you more details.

You might think how I could able to reference ICustomerServiceAsync and Customer classes in my Silverlight client. What I did here is I created a Silverlight class library and add ICustomerAsync and Customer class as a link. In VS we can do it by selecting add existing item and rather than clicking on the Add button, click on the arrow on the right side of the Add and select as link from the option.

In the above client code I used lambda expression to call the service. You can also use a anonymous delegate or Callback method to achieve the same.

One important thing you need to add to our WCFService host project is clientaccesspolicy.xml, other wise Silverlight client will not be able to communicate and throws Security exception. Below is the policy file

<?xml version="1.0" encoding="utf-8"?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from http-request-headers="*">
        <domain uri="*"/>
      </allow-from>
      <grant-to>
        <resource path="/" include-subpaths="true"/>
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>

 

To test my connection and exceptions I used a Winform application. Silverlight wont give proper error details.

Download the code here

 

 

Written by Sony Arouje

October 1, 2010 at 7:14 pm

12 Responses

Subscribe to comments with RSS.

  1. […] I demonstrated two ways of interacting with WCF service in the source code I uploaded. A proxy and proxy less approach. We all know the proxy approach, the communication to the service using the class generated by VS. In one of my post I provided some insight of Proxy less approach, you can check it out here. […]

  2. Hey What is the advantage of using proxy less service(communication) rather creating proxy.

    Sandeep

    January 5, 2011 at 5:21 am

    • As I told in the post I am not a big fan of using Proxy generated by tools. I don’t feel full control on my code if some generated code exist. The advantage of Proxyless communication is a clean proxy hand written by you. Proxy less approach may not work out if the service is hosted by third party and we are consuming it.

      sonyarouje

      January 5, 2011 at 10:36 am

  3. Thanks; I was looking for the similar approach.

    Ashraf

    February 3, 2011 at 1:00 am

  4. Hi,
    What about if you wont to add a real database, how you will add a DataContract to SilverlightClassLibrary? If datalayer is built over Entity Framework you can not add refereney to it.

    Tiho

    February 21, 2011 at 4:56 pm

    • You can use DTO’s or you can go for EF POCO model or fall back to proxy approach.

      sonyarouje

      February 21, 2011 at 5:21 pm

  5. Thanks a lot Sony, I had no idea you could do that. I hate adding service references. I was looking for this kinda approach for a long time and I luckily stumbled on your blog post.

    Sai Gudigundla

    September 4, 2011 at 8:51 am

  6. Hi Sony. Great post, and really useful for something I’m looking at right now. I was just wondering how this would look if you have a method in the web service that has parameters?

    codemonkey78

    October 18, 2012 at 4:58 pm

    • Thanks for your comment. I am not remembering how I used it with a param. I think you can try like below

      [OperationContract(AsyncPattern = true)]
      IAsyncResult BeginGetCustomerList(string firstName, AsyncCallback callback, object state);

      Let me know how it works.

      Sony Arouje

      October 18, 2012 at 6:43 pm

  7. […] I also needed to get rid of the old web references and build the proxy dynamically as well (because the endpoint will vary), and found this useful article which outlines how to build dynamic proxies https://sonyarouje.com/2010/10/01/proxy-less-silverlight-wcf-communication. […]

  8. Please provide the full code because download link is not working

    Shyam

    December 29, 2015 at 11:40 am


Leave a reply to sonyarouje Cancel reply