Mike Taulty's Blog
Bits and Bytes from Microsoft UK
Silverlight 2 - Talking to a Local WCF Service from a Silverlight Application
Mike Taulty's Blog

Mike's Badges

Follow on Twitter
View mike's profile on slideshare
Add to Technorati Favorites
CW Blog Awards

This really falls into the category of "just because it's there" because it's something I was thinking about earlier today and wanted to experiment with.

Silverlight 2 applications can make web service calls across domain boundaries if the domain that they are calling to allows that. So, I was thinking about a scenario where perhaps I've got a local application installed such as a WPF application or perhaps a Vista Sidebar gadget and I go and visit a Silverlight website and the Silverlight client can notify the installed application and cause it to maybe "light up" in some fashion.

That is, a Silverlight 2 application communicating with another application that's installed and running on the local machine.

Before Silverlight will allow a cross-domain call it requests one of two files from the root of the site that it's calling to. I chose to use clientaccesspolicy.xml.

So, I wrote a quick "WCF Service" using the System.ServiceModel.Web stuff from .NET Framework V3.5. Service looks like this;

[ServiceContract]
public interface IHandlePolicy
{
  [OperationContract]
  [WebInvoke(UriTemplate = "clientaccesspolicy.xml", Method="GET", BodyStyle=WebMessageBodyStyle.Bare)]
  XElement ReturnPolicy();
}

so if you request a URL clientaccesspolicy.xml then what I'll do is this;

public class PolicyHandler : IHandlePolicy
{
  public XElement ReturnPolicy()
  {
    return (XElement.Load("policy.xml"));
  }
}

and that policy.xml file simply looks like this;

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

I configured that up like this;

     <service name="PolicyHandler">
        <endpoint address="http://localhost:9091/"
                  binding="webHttpBinding"
                  contract="IHandlePolicy"
                  behaviorConfiguration="webHttpBehaviour"/>
      </service>

 

and with a behaviour like this;

      <endpointBehaviors>
        <behavior name="webHttpBehaviour">
          <webHttp/>
        </behavior>
      </endpointBehaviors>

 

and serving it up with code;

  static void Main(string[] args)
  {
    WebServiceHost webHost = new WebServiceHost(typeof(PolicyHandler));
    webHost.Open();

    Console.WriteLine("Listening...");
    Console.ReadLine();
    
    webHost.Close();
  }

So, now if I request URL http://localhost:9091/clientaccesspolicy.xml then this service will reply with my policy file.

I then added into the same project another SOAP based service. Aside - I was going to use a the System.ServiceModel.Web stuff here as well but then discovered that Silverlight does not seem to have the webHttpBinding or the WebInvoke/WebGet bits of .NET Framework V3.5 in the beta so I went with SOAP messages to a separate service listening on a sub path of the initial URI.

Here's the service;

[ServiceContract]
public interface IPrintMessages
{
  [OperationContract]
  void PrintMessage(string message);
}

and the implementation (not too exciting);

public class MessagePrinter : IPrintMessages
{
  public void PrintMessage(string message)
  {
    Console.WriteLine(message);
  }
}

and the configuration;

 <service name="MessagePrinter"
               behaviorConfiguration="metadataBehaviour">
        <endpoint address="http://localhost:9091/printer"
                  binding="basicHttpBinding"
                  contract="IPrintMessages"/>

 

<serviceBehaviors>
        <behavior name="metadataBehaviour">
          <serviceMetadata httpGetEnabled="true"
                           httpGetUrl="http://localhost:9091/printer"/>
        </behavior>
      </serviceBehaviors>

 

and, finally, the hosting code now looks like;

  static void Main(string[] args)
  {
    WebServiceHost webHost = new WebServiceHost(typeof(PolicyHandler));
    webHost.Open();

    ServiceHost soapHost = new ServiceHost(typeof(MessagePrinter));
    soapHost.Open();

    Console.WriteLine("Listening...");
    Console.ReadLine();

    soapHost.Close();
    webHost.Close();
  }

I built a quick Silverlight application with a TextBox and a Button, added a Service Reference to my web service by pointing at the WSDL file and then wrote a little code;

public partial class Page : UserControl
  {
    public Page()
    {
      InitializeComponent();
    }
    private void Button_Click(object sender, RoutedEventArgs e)
    {
      PrintMessagesClient proxy = new PrintMessagesClient();
      proxy.PrintMessageAsync(myText.Text);
    }
  }

and, hey presto, I can see Silverlight requesting my clientaccesspolicy.xml file at runtime and then calling my service and I have my Silverlight app talking to my local app;

image

Now...whether there's actually a good use for that is another question but it was fun to me for a little while :-)

I put the zipped up project files here in case you want to play with them.


Posted Thu, Mar 27 2008 5:06 PM by mtaulty
Filed under:

Comments

どっとねっとふぁんBlog wrote ローカルなWCFサービスとSilvelightの連携
on Fri, Mar 28 2008 2:04 AM
Silverlight 2 - Talking to a Local WCF Service from a Silverlight Application  どんな場合に使える技術か、というのは難しいものがありますが(w...
Mike Taulty's Blog wrote Silverlight 2 - Update to previous post around clientaccesspolicy.xml
on Fri, Mar 28 2008 3:00 AM
Just an update to this post as I got a little worried after publishing it :-) In case it wasn't obvious...
Community Blogs wrote Silverlight Cream for March 28, 2008 -- #239
on Fri, Mar 28 2008 10:08 AM
Jose Fajardo continues with Login UI for Messenger, Jeff Paries with very cool DrumPad, Jesse Liberty
(C) Mike Taulty, 2009. All rights reserved. The information in this weblog is provided "AS IS" with no warranties, and confers no rights. This weblog does not represent the thoughts, intentions, plans or strategies of my employer. It is solely my opinion. Inappropriate comments will be deleted at the authors discretion. All code samples are provided "AS IS" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and/or fitness for a particular purpose.
Powered by Community Server (Non-Commercial Edition), by Telligent Systems