Getting Started with WCF Services in WinRT

I have been learning WInRT in my “spare time” since for a while now. My big interest is working with data in Metro style applications for Windows 8. In this post I will describe step-by-step instructions of creating a WinRT application that is using WCF Service. I am going to use XAML application. To get started, just create a brand new XAML based application in Visual Studio 11. Then I am going to create a WCF Service that is using Entity Framework code first.

I created just on table/class, data context and a WCF host web application.

public class Session

{

    public int SessionID { get; set; }

    public string Title { get; set; }

    public string Description { get; set; }

    public string Speaker { get; set; }

    public DateTime When { get; set; }

}

using System.Data.Entity;

using WinRT.Data;

namespace WinRT.DataAccess

{

    public class Context : DbContext

    {

         public Context() :

           base("Name=VSLive")

         {

         }

         public DbSet<Session> Sessions { get; set; }

         protected override void OnModelCreating(DbModelBuilder modelBuilder)

         {

             base.OnModelCreating(modelBuilder);

             modelBuilder.Entity<Session>().

                     Property(p => p.Title).HasMaxLength(100).IsRequired();

             modelBuilder.Entity<Session>().

                     Property(p => p.Speaker).HasMaxLength(50).IsRequired();

             modelBuilder.Entity<Session>().

                     Property(p => p.Description).IsRequired();

             modelBuilder.Entity<Session>().

                     Property(p => p.When).IsRequired();

           }

      }

}

Service class is not very complicated either, here is get method:

public Session[] GetList()

{

      using (var context = new Context())

      {

           context.Configuration.LazyLoadingEnabled = false;

           context.Configuration.ProxyCreationEnabled = false;

           return context.Sessions.ToArray();

       }

}

Now, I am going to configure service to use IIS and setup AppPool to have enough rights to create a database.

Now in my XAML Metro application I right click on references and choose Add Service Reference. I will clock on button in the next dialog to discover services in the solution and click OK to add a reference. This will create a proxy class to communicate with my service. One interesting thing about this class in comparison with the same proxy in .NET or Silverlight is that it is using new async / await keywords and Tasks to simplify the code on the client.

Now, I am going to add a view model class that will have all the communication with the service. First of all, it has to create proxy instance with proper configuration.

private VSLiveServiceClient _client;

private void SetupClient()

{

      BasicHttpBinding binding =
           new BasicHttpBinding(BasicHttpSecurityMode.None);

      binding.AllowCookies = true;

      binding.MaxBufferSize = int.MaxValue;

      binding.MaxReceivedMessageSize = int.MaxValue;

      binding.OpenTimeout = TimeSpan.FromSeconds(10);

      EndpointAddress address = new EndpointAddress(_serviceUri);

      _client = new VSLiveServiceClient(binding, address);

}

Now I can invoke the service by calling the proxy:

public async Task LoadData()

{

      var sessions = await _client.GetListAsync();

      Sessions = new ExtendedObservableCollection<Session>(sessions);

}

You can read a bit more about my ExtendedObservableCollection in one of my previous posts at http://dotnetspeak.com/index.php/2011/11/observablecollectiont-in-winrt/. Now I am ready run. But what I am getting is “There was no endpoint listening at ….” The issue is that I have to add an exemption to allow WinRT application to communicate with a service at localhost. The tool is called CheckNetIsolation. You can get to it by running Visual Studio Command prompt. But you have to find the application ID for that. To do so you have to run RegEdit and find your application. Here is path you are looking for:

HKEY_CURRENT_USERSoftwareClassesLocal SettingsSoftwareMicrosoftWindowsCurrentVersionAppContainerMappings

Once you find the path, just go through all nodes and look for you application by looking at DisplayName entry node. Once you find it, click on a node name(starts with S-1-…), select Rename and hit Ctrl+C to copy node name to the clipboard.

image

Mine was S-1-15-2-4269264600-3040727888-3229327272-2989798893-2153435301-719469956-2341848450.

Now in VS Command prompt type :

CheckNetIsolation LoopbackExempt -a -p=S-1-15-2-4269264600-3

040727888-3229327272-2989798893-2153435301-719469956-2341848450

and hit enter. Make sure you spell everything correctly, the command line is case-sensitive.

Now, run your application. You should be ready to go. If you still get an error, edit the manifest file (double-click on Package.appxmanifest file in your WinRT project, go to capabilities tab and check home networking and Internet Client.

image

You will also need to turn off (or configure) Windows Firewall.

You are now ready to go.

Thanks.

5 Comments

  1. Pingback: Creating WCF Service with SOAP/REST Endpoints « Sergey Barskiy's Blog

  2. Not as far as I know. Although, one could argue that tere is not much point in that because your app comes through the store and is isntalled as a package. There is a settigns class that stores stuff in isolated storage, but I do not think this is what you are looking for. You can always have an intermediate service that gives you a url to a real service you can store in Settings.

  3. Hi. I am having some problems with WinRT-WCF interaction.
    AuthenticationService of WCF does not work with WinRT. And it seems like there is no solution to develop a *secured* web service to be consumed by a WinRT client. Do you have any clues?

    Thanks!

Leave a Reply

Your email address will not be published. Required fields are marked *