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.]

Comments

  • Anonymous
    September 05, 2014
    Tried to remake this in my own application because it was exactly what I was looking for now that normal service references are out of the Picture. BUT, I couldn't get it to Work. The messagebox was just an empty string and when I debug the response returns 404 even though I can open the url http://localhost:18362/Service1.svc/GetData and get the same result as you. I even tried downloading ur sample and run that instead. Same story. ;(

  • Anonymous
    September 05, 2014
    Forget what I wrote. You don't want to hear the reason. Just thank you a lot for this :)

  • Anonymous
    September 30, 2014
    Hi, Flemming When debugging the response return 404 not found, could you plese helpe me

  • Anonymous
    November 03, 2014
    I created the service reference in VS2012 then opened the solution in VS2013 I have all method, but calling any method doesn't nothing return.

  • Anonymous
    November 11, 2014
    Being new to Windows 8.1 Phone development I've found this really helpful. I have the example running well on my machine but have some questions... Does the WCF web service get installed on the phone along with the app? How do I pass parameters through to the web service? I am assuming this would also handle complex data types?

  • Anonymous
    November 14, 2014
    WOW. Great tutorial works fine in my case. Thanks. :)

  • Anonymous
    December 17, 2014
    Hi, i try to turn your example on my Nokia Lumia 830 and i have the response returns "404 Not Found". I don't know why. Thanks

  • Anonymous
    February 26, 2015
    Flemming! I have the same problem! What am I missing??? you found it...

  • Anonymous
    March 01, 2015
    in the localhost url, give ur port number instead of 18362

  • Anonymous
    April 04, 2015
    how to pass parameters to this code?

  • Anonymous
    April 09, 2015
    I have used my own port in the localhost Url but still I'm not receiving the response. 404 Not Found, @Fleming - what did you do man?

  • Anonymous
    April 09, 2015
    I tried hosting the service on the IIS on a server. Now I'm getting status code 504 - Gateway Timeout. But I'm able to browse the url and data is coming in the XML format.

  • Anonymous
    June 02, 2015
    So, any ideas how we can access our services ?? I have the same problem

  • Anonymous
    June 05, 2015
    but how can i RETURN just the Message and not the all stuff

  • Anonymous
    July 07, 2015
    Thanks very much for this rare tutorial ! I just read that Microsoft recommands using Windows.Web.Http instead of System.Net.Http from Windows 8.1 : msdn.microsoft.com/.../hh781239.aspx The code of function CallService would be shorter then : <Code>        private async void CallService()        {            HttpClient httpClient = new HttpClient();            string data = await httpClient.GetStringAsync(new Uri("http://localhost:60347/FilmService.svc/GetData"));            var dialog = new MessageDialog(data);            await dialog.ShowAsync();        } </Code>