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 service from 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 http://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 –> http://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, "http://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 (15)

  1. Flemming says:

    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. ;(

  2. Flemming says:

    Forget what I wrote. You don't want to hear the reason. Just thank you a lot for this 🙂

  3. Francisco says:

    Hi, Flemming

    When debugging the response return 404 not found, could you plese helpe me

  4. Lenny says:

    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.

  5. Karl says:

    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?

  6. Janak says:

    WOW. Great tutorial works fine in my case. Thanks. 🙂

  7. Mick says:

    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

  8. Bryan says:

    Flemming! I have the same problem! What am I missing??? you found it…

  9. Dinesh says:

    in the localhost url, give ur port number instead of 18362

  10. hussain says:

    how to pass parameters to this code?

  11. Phanish says:

    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?

  12. Phanish says:

    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.

  13. Prolls says:

    So, any ideas how we can access our services ?? I have the same problem

  14. Nathiel says:

    but how can i RETURN just the Message and not the all stuff

  15. Beb says:

    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&quot;));

               var dialog = new MessageDialog(data);

               await dialog.ShowAsync();

           }

    </Code>