Calling a WCF service from your Silverlight application
Yesterday I talked about calling a traditional ASMX web service from your Silverlight app. Today, I'll be talking about WCF services. As I've said yesterday, in the current release, you only have tool support for getting a proxy to an ASMX web service (well, at least I've tried getting a web reference to a WCF service and it simply didn't work - maybe i'm doing something wrong). However, nothing prevents you from creating your own proxy to make the call to a WCF service.
Since the alpha version only understands JSON when it calls ASMX services, I'm also assuming that is the only way you have to get info from a WCF service. That being the case, you must start by configuring your service to use JSON as its message enconding format.
After doing that, it's only a matter of creating a new proxy class. Let me illustrate this with a quick example. Lets start by creating the dummy service:
[ServiceContract]
public interface ITest
{
[OperationContract]
S DoWork();
}
public class Test : ITest
{
public S DoWork()
{
S a = new S();
a.Address = "Funchal";
a.Name = "Luis";
return a;
}
}
Don't forget to add the svc file :) (not shown here because there really isn't much to show, right). As you can see, this is really a stupid service which returns an object that only has two properties. Here's the S class (just for the sake of completeness):
[DataContract]
public class S
{
[DataMember(Name="Name")]
private string name = "Luis";
[DataMember(Name="Address")]
private string address= "Funchal";
public string Name
{
get { return name; }
set { name = value; }
}
public string Address
{
get { return address; }
set { address = value; }
}
}
Now, the fun begins :) You must start by definig the S class in your silverlight project. You can do this in several ways:
- you can add an existing cs file and then choose the link option (instead of clickin in the add button);
- you might have built a dll with the previous type and then add it as reference to the service and silverlight projects;
- there's always the old copy/paste approach :)
After doing that, you need to build a new type (the proxy) which you'll be using to communicate with the service. You must really build a new class because all the cool methods of the the SoapHttpClientProtocol class that you need to make the service calls are protected (the truth is that nothing prevents you from using the BrowserHttpWebRequest class and then using the JavaScriptSerializer to serialize/deserialize the values. If you find this funny, then by all means, go ahead and do it; i prefer to build the class in 30 seconds and then hit the coach to watch tv :)) . Here's a simple proxy that lets you invoke the DoWork method in a sync fashion:
public class MyProxy:SoapHttpClientProtocol
{
public S DoWork()
{
object[] obj = this.Invoke("DoWork", new ServiceParameter[0], typeof(S));
return (S)obj[0];
}
}
Do notice the new ServiceParameter[0] value passed as the 2nd parameter of the Invoke method (needed because the method doesn't receive any parameters; if it expected parameters, you just need to pack them in an array and pass them to the Invoke method)...Getting the async methods is as easy as adding 2 methods which call the BeginInvoke/EndInvoke methods inherited from the base class. Using the proxy is really simple, as you can see from the following code:
MyProxy proxy = new MyProxy();
proxy.Url = "url to the service";
S aux = proxy.DoWork();
Debug.WriteLine(aux.Name +"-"+ aux.Address);
And that's all for today.