Workaround to adding Service Reference to Windows Phone 8.1 (Runtime app)

I’ve got lots of queries recently from fellow developers about their inability to consume WCF services from Windows Phone 8.1 Runtime app. Apparently, adding a service reference (for WCF Services) to the project via Visual Studio is currently available for Windows Phone 8.0, Windows Phone 8.1 Silverlight and Windows 8.1 projects but not for Windows Phone 8.1 Runtime project.

How to consume WCF service / add service reference to Windows Phone 8.1:

 

Scenario 1: Building Windows Phone 8.1 Silverlight

Just right click on reference and click ‘Add Service reference’ and proceed with the way you are used to.

image

Scenario 2: Building Windows Phone 8.1 Runtime app / Universal app

For this one, a direct way doesn’t seem to be available in the time being, a workaround exists though that I thought I should share. To sum it up, you need to add a REST endpoint to your WCF service and then make REST calls from your Windows Phone app.

Here’s a quick tutorial from scratch

2.1 Creating a Windows Phone 8.1 Runtime app and a WCF Service Application:

1. In my SUPER SIMPLE example I created a blank app (Windows Phone) called “Consume WCF from WP8.1 Sample” and added a WCF Service Application to my solution and called it “REST WCF Service

image

2. In the IService1.cs file, I only kept the below Operation Contract and removed the parameters for simplicity

 [ServiceContract]
 public interface IService1
 {
  
     [OperationContract]
     string GetData();
  
     // TODO: Add your service operations here
 }

3. In the Service1.svc.cs file, update the Service1 class that implements the new interface to be as below:

 public class Service1 : IService1
 {
     public string GetData()
     {
         return "WCF Service";
     }
 }
2.2 In Just 2 Steps, Expose a REST interface of our ‘REST WCF Service’ to be able to call it from Windows Phone 8.1 Runtime:
Step1:

Add the WebGetAttribute and WebInvokeAttribute to your OperationContract as in Line 6 the below example:

    1: [ServiceContract]
    2: public interface IService1
    3: {
    4:  
    5:     [OperationContract]
    6:     [WebGet(UriTemplate = "GetData")]
    7:     string GetData();
    8:  
    9:     // TODO: Add your service operations here
   10: }
Step2:

It’s time to put the final touch to the WCF Service. To make it RESTful, we need to update the configuration ‘web.config’ file by adding endpoint behavior as in Lines 15-21  then Update the endpoint by changing the binding to webHttpBinding and finally point to the behavior created by adding the behviorConfiguration to the endpoint node as in Lines 2-15

    1: <system.serviceModel>
    2:   <!--UPDATE the ENDPOINT by Changing the binding to webHttpBinding-->
    3:   <!--POINT to the endpointBehavior Created below by ADDing behaviorConfiguration to the endpoint node-->
    4:   <services>
    5:     <service behaviorConfiguration="MyServiceBehavior" name="REST_WCF_Service.Service1">
    6:       <endpoint address="" binding="webHttpBinding" behaviorConfiguration="web" contract="REST_WCF_Service.IService1">
    7:         <identity>
    8:           <dns value="localhost"/>
    9:         </identity>
   10:       </endpoint>
   11:       <endpoint address="max" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
   12:     </service>
   13:   </services>
   14:   <behaviors>
   15:     <!--BEGIN ADD ENDPOINT BEHAVIOR-->
   16:     <endpointBehaviors>
   17:       <behavior name ="web">
   18:         <webHttp />
   19:       </behavior>
   20:     </endpointBehaviors>
   21:     <!--END of ADD ENDPOINT BEHAVIOR-->
   22:     <serviceBehaviors>
   23:       <behavior name="MyServiceBehavior"> <!--ADDED MyServiceBehvior-->
   24:         <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
   25:         <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
   26:         <!-- 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 -->
   27:         <serviceDebug includeExceptionDetailInFaults="false"/>
   28:       </behavior>
   29:     </serviceBehaviors>
   30:   </behaviors>
   31:   <protocolMapping>
   32:       <add binding="basicHttpsBinding" scheme="https" />
   33:   </protocolMapping>    
   34:   <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
   35: </system.serviceModel>

--> Your WCF Service is now RESTful (i.e. can be called from Windows Phone 8.1 Runtime app)

2.3 Call RESTful WCF Service from Browser or Windows Phone 8.1 Runtime app

You can test your servicefrom the browser or your Windows Phone 8.1 Runtime app to see the result.

Browser:

I launched it in Internet Explorer and my URL was https://localhost:18362/Service1.svc. Now, I can point to my REST url by appending the method name that I specified in the UriTemplate attribute (GetData) to my .svc uri –> https://localhost:18362/Service1.svc/GetData

You should get the following:

image

Phone:

    1: private async void CallService()
    2: {
    3:     HttpClient httpClient = new System.Net.Http.HttpClient();
    4:     HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "https://localhost:18362/Service1.svc/GetData");
    5:     HttpResponseMessage response = await httpClient.SendAsync(request);
    6:     string data = await response.Content.ReadAsStringAsync();
    7:     var dialog = new MessageDialog(data);
    8:     await dialog.ShowAsync();
    9:  
   10: }

You should get the following:

image

You may download the full solution from here.

I hope this was helpful.

Kindly share with your developers and community.

Please feel free to subscribe to my blog or follow me on twitter for alerts on posts.

Mohamed Yamama,   
@m_yamama

[Please read the DISCLAIMER for this blog here.]