Silverlight front end calling to WCF Service, all in one Windows Azure Web Role Sample

I was asked recently to provide a sample which has Windows Azure Web Role with Silverlight front end, calling to WCF service which is hosted in the same Windows Azure Web Role. I decided to share those details and sample with everyone. This sample is very back code generate all through respective wizard and templates. I just added a few things to get them all working in one sample.

 

Create a cloud project name SLWCFWebRole and add WCF Service Web Role name WCFServiceWebRole as below:

 

 

Now add a new Silverlight project name SilverlightApp to your SLWCFWebRole application which is set to have:

  1. SilverlightApp is hosted in existing Web Role
  2. “Enable WCF RIA Services” to connect with WCF Service hosted in SLWCFWebRole

 

 

Now we need to add the WCF Service reference to our SilverlightApp. You can use several ways to get it included in the application.

Here, I just launched, WCFServiceWebRole in my browser so I can get active service URL (https://localhost:37000/Service1.svc ) to add in my SilverlightApp:

 

 

Once I have the active service URL https://localhost:37000/Service1.svc I added it to my SilverlightApp as below:

 

After it you will see that ServiceReference1 is included in your SilverlightApp as below:

 

 

If you open ServiceReferences.ClientConfig you will see the URL for the Web Service as below:

<configuration>

    <system.serviceModel>

        <bindings>

            <basicHttpBinding>

                <binding name="BasicHttpBinding_IService1" maxBufferSize="2147483647"

                    maxReceivedMessageSize="2147483647">

                    <security mode="None" />

                </binding>

            </basicHttpBinding>

        </bindings>

        <client>

            <endpoint address="https://localhost:37000/Service1.svc" binding="basicHttpBinding"

                bindingConfiguration="BasicHttpBinding_IService1" contract="ServiceReference1.IService1"

                name="BasicHttpBinding_IService1" />

        </client>

    </system.serviceModel>

</configuration>

 

Very Important:

  1. You should remember that when your WCF Web Role application will run in Compute Emulator it will not use https://localhost/* instead it will use IP address as https://127.0.0.1:81/
  2. Also when the same application will run in Windows Azure cloud the URL will be something https://<your_service_name>.cloudapp.net
  3. So when you run this application in Compute Emulator or Windows Azure Cloud, you would need to change the about endpoint address to correct one.

 

Now let’s add necessary code in SilverlightApp to make a call to WCF Service as below:

 

Edit MainPage.xaml to add one label and TextBox name TextBox1 as below:

 

 

Now edit MainPage.xaml.cs as below to initialize WCF Service reference ServiceReference1 and then implement a call to service contact “GetData” as below:

 

    public partial class MainPage : UserControl

    {

        public MainPage()

        {

            InitializeComponent();

             ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();

            client.GetDataCompleted += new EventHandler<ServiceReference1.GetDataCompletedEventArgs>(client_GetDataCompleted);

            client.GetDataAsync(20); // Here we are passing integer 20 from Silverlight app to WCF Service

        }

 

        void client_GetDataCompleted(object sender, ServiceReference1.GetDataCompletedEventArgs e)

        {

            textBox1.Text = e.Result.ToString();

            // Here we are receiving the results "string + Int value" from WCF Service and then writing into

            // Silverlight app text box

        }

    }

 

Now set SilverlightAppTestPage.aspx as your startup page in WCFServiceWeRole and launch your application in Compute Emulator.

 

You will see the web page was launched however you will see the following Exception:

 

Error: An error occurred while trying to make a request to URI 'https://localhost:37000/Service1.svc'. This could be due to attempting to access a service in a cross-domain way without a proper cross-domain policy in place, or a policy that is unsuitable for SOAP services. You may need to contact the owner of the service to publish a cross-domain policy file and to ensure it allows SOAP-related HTTP headers to be sent. This error may also be caused by using internal types in the web service proxy without using the InternalsVisibleToAttribute attribute. Please see the inner exception for more details.

 

 

The exception occurred only because ServiceReferences.ClientConfig is pointing to https://localhost:37000/Service1.svc to connect to WCF Service which is wrong as we are running this application in Windows Azure Compute Emulator at https://127.0.0.1:81/Service1.svc as below:

                                                                                                                                    

 

Now let modify ServiceReferences.ClientConfig to point correctly to WCF Service in compute Emulator as below:

 

<configuration>

    <system.serviceModel>

            ……..

        <client>

            <endpoint address="https://127.0.0.1:81/Service1.svc" binding="basicHttpBinding"

                bindingConfiguration="BasicHttpBinding_IService1" contract="ServiceReference1.IService1"

                name="BasicHttpBinding_IService1" />

        </client>

    </system.serviceModel>

</configuration>

 

Run the application again in Windows Azure Compute Emulator and you will see the correct and expected result as below:

 

 

 

Now to run this application in Windows Azure, you can add clientaccesspolicy.xml in the WCFServiceWebRole application as below:

 

<?xml version="1.0" encoding="utf-8"?>

<access-policy>

  <cross-domain-access>

    <policy>

      <allow-from http-request-headers="SOAPAction">

        <domain uri="*"/>

      </allow-from>

      <grant-to>

        <resource path="/" include-subpaths="true"/>

      </grant-to>

    </policy>

  </cross-domain-access>

</access-policy>

 

Now you can deploy this application to Windows Azure Cloud however you would need to make a necessary change to reflect correct WCF endpoint URL when application is running in Windows Azure Cloud. This change is made again in ServiceReferences.ClientConfig.

 

For example your Windows Azure service name is “TestSLWCFWebRole” then you can edit ServiceReferences.ClientConfig as below:

 

<configuration>

    <system.serviceModel>

            ……..

        <client>

            <endpoint address="https://testslwcfwebrole.cloudapp.net/Service1.svc" binding="basicHttpBinding"

                bindingConfiguration="BasicHttpBinding_IService1" contract="ServiceReference1.IService1"

                name="BasicHttpBinding_IService1" />

        </client>

    </system.serviceModel>

</configuration>

Now you can package and deploy this service to Windows Azure Service TestSLWCFWebRole, production slot and you will see the correct and expected results:

 

You can download the full sample from codeplex: