8 Comments
 

WCFXamarinTitleLogo

Windows Communication Foundation (WCF) used to be the way how web services were created in .Net. Allegedly it comes at no surprise that many backend services are implemented with WCF and therefore if you are in the business of writing mobile clients may face the task of integrating such a service. In this post we will look at how a WCF service can be integrated into a Xamarin.Forms app and how Begin/End async methods can be wrapped into task based async/await methods which are the defacto standard since C# 5/.Net 4.5.

In this blog post we will look at the following:

  1. Looking WCF web service that can run on IIS or Azure
  2. Creating the Xamarin.Forms App
    1. Add UI for interaction
    2. Add service reference in the Portable Class Library (PCL)
  3. Mapping to the new async/await model

The basic setup

Lets first have a look at how the app and the web service are setup before we do the final wiring up of the service.

Looking at the WCF web service

The WCF service I’m using for this sample code, which you can find as usual on GitHub, is a WCF Application. A WCF Application can run on IIS and be easily deployed to Azure which makes it perfect for getting up and running in no time without having to mess with IIS Express Firewall settings.

The service we will be integrating has a single method which will take an int and return a string, here is the interface definition:

[ServiceContract]
public interface IWcfService
{
[OperationContract]
string GetData(int value);
}

And the implementation is equally simple:

public class WcfService : IWcfService
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
}

So as you can see the service method GetData takes an int wraps it in a string and will send it back to the caller. Now lets have a look at the client and the UI.

Xamarin.Forms project setup

Now on the client we will setup a XAML based Xamarin.Forms application with a PCL as core library. The app will be a single page app that displays a Picker, Button and Labelcontrol which will look like this on XAML:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="WcfIntegrationXamarinForms.View.MainPage">
<StackLayout VerticalOptions="Center" HorizontalOptions="Center">
<Picker x:Name="NumberPicker" SelectedIndex="{Binding SelectedNumberIndex}">
<Picker.Items>
<x:String>1</x:String>
<x:String>2</x:String>
<x:String>3</x:String>
<x:String>4</x:String>
<x:String>5</x:String>
<x:String>6</x:String>
<x:String>7</x:String>
<x:String>8</x:String>
<x:String>9</x:String>
<x:String>10</x:String>
</Picker.Items>
</Picker>
<Button Text="Submit" Command="{Binding SubmitCommand}"></Button>
<ActivityIndicator IsRunning="{Binding IsCallingWebservice}"></ActivityIndicator>
<Label Text="{Binding Response}" />
</StackLayout>
</ContentPage>

Notice that the Picker does not allow to set the Items programmatically and only provides the SelectedIndex to get information on the selected item. Now at the back of the view we will be using a ViewModel based on MVVM Light, to which you can find a basic introduction here. The view model manages the inputs from the view calls the IWcfServiceWrapper and pushes the result back to the UI. Here is the implementation of the View Model:

public class MainViewModel : ViewModelBase
{
private readonly IWcfServiceWrapper _wcfServiceWrapper;
private string _response;
private readonly IList<string> _numbers;
private bool _isCallingWebservice;

/// <summary>
/// Initializes a new instance of the MainViewModel class.
/// </summary>
public MainViewModel(IWcfServiceWrapper wcfServiceWrapper)
{
if (wcfServiceWrapper == null) throw new ArgumentNullException("wcfServiceWrapper");
_wcfServiceWrapper = wcfServiceWrapper;

_numbers = new List<string> {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"};
Response = "Pick a number and click submit";
SubmitCommand = new RelayCommand(GetResponseAsync, () => CanGetResponse);
CanGetResponse = true;
}

private async void GetResponseAsync()
{
CanGetResponse = false;
IsCallingWebservice = true;

Response = await _wcfServiceWrapper.GetDataAsync(Int32.Parse(_numbers[SelectedNumberIndex]));

CanGetResponse = true;
IsCallingWebservice = true;
}

public int SelectedNumberIndex { get; set; }

public bool CanGetResponse { get; set; }

public ICommand SubmitCommand { get; set; }

public bool IsCallingWebservice
{
get { return _isCallingWebservice; }
set
{
if (value == _isCallingWebservice) return;
_isCallingWebservice = value;
RaisePropertyChanged(() => IsCallingWebservice);
}
}

public string Response
{
get { return _response; }
set
{
if (_response == value) return;
_response = value;
RaisePropertyChanged(() => Response);
}
}
}

We simply implement the command which enables the ActivityIndicator to show a progress bar while we are waiting for our response.

Integrating the service

We will integrate the WCF service in the PCL which will allow us to use the interface for each platform. This approach is also valid when you develop for one single platform such as Windows (Phone), Android or iOS, so I really recommend you choose to implement your service in a PCL even if for now you are only targeting one platform. Adding WCF services i.e. creating the proxy classes and calls has always been a very trivial process and hasn’t changed in the modern world. Expand the PCL project, right click on References and select Add Service Reference…enter the URL of your web service and click OK.

AddServiceReference

This will generate all the necessary proxy classes and definitions so you can call the Webservice. Unfortunately though all the asynchronous are implemented with the Begin/End asynchronous pattern. Luckily we can easily wrap those calls and use the newer async/await model of asynchronous programming with C#.

Mapping to the new async/await model

With the Task library we get the TaskFactoryclass which has a FromAsync method which lets us wrap Begin/End async methods into a single awaitable task based asynchronous call. So we can add a WcfServiceWrapper.cs to our portable project which wraps the call as follows:

public class WcfServiceWrapper:IWcfServiceWrapper
{
private IWcfService _wcfService;

public WcfServiceWrapper(IWcfService wcfService)
{
if (wcfService == null) throw new ArgumentNullException("wcfService");

_wcfService = wcfService;
}

public async Task<string> GetDataAsync(int number)
{
Task<string> getDataTask = new TaskFactory().FromAsync<int,string>(_wcfService.BeginGetData, _wcfService.EndGetData, number, null, TaskCreationOptions.None);
return await getDataTask;
}
}

Conclusion

We looked at how a simple WCF service can be integrated in a Xamarin.Forms mobile app. Further the post shows you how you can wrap the Begin/End asynchronous pattern into todays async/await task based async pattern.

You can find the entire project on GitHub.

This post was originally posted on the Noser Blog.

Comments

Comment by Jose Villaro

Hi, I really appreciate you took the time to make this post.
I'm trying to do this but I have a little problem, I'm using Visual Studio 2015 and I can't add a Service Reference to a PCL, the right click pop up does not show this option. Have you seen this? Is there a work around?
Thanks in advance

Jose Villaro
Comment by Mark

Hi Jose, thank you for your kind words :) What platforms are you supporting with your PCL? If I remember correctly WP8.1 (non-silverlight) does not support WCF clients which could be a reason for the effect you are seeing. I checked on a PCL project supporting iOS, Android and Win10 and was able to add a WCF client reference.

Comment by Ronak Vala

Hey Mark, Thanks for the blog post and specially for the comment to Jose. I was trying to find a workaround on adding service reference from past few hours and I was about to lose hope on adding WCF service to a PCL project but yeah you saved me :)

Ronak Vala
Comment by Simon

Hi Mark, I am also unable to add a WCF 'Service Reference' to a PCL project (for Android, iOS, and Windows Phone) in VS 2015 Prof. Only options are Reference, Connected Service (cloud). I can add a 'Web Reference' to an Android specific library, but this doesn't seem to work the same way as a Service Reference. The resulting proxy does not contain constructors that allow setting the binding and endpoint. I am reluctant to use the SLSvcUtil to generate the proxy as code generation steps make things more difficult to automate. Any ideas?

Simon
Comment by Mark

@Simon thanks for your feedback. Which Windows Phone stack have you selected? I can add Service Reference to the PCL in the sample code. You can see the targeted Platforms by right clicking on the project -> Properties -> Library.

Comment by Dominic

@Simon, you might have already found this, but if you right-click on the project, select properties, and then clear all the windows 8 and 8.1 targets from your list you should get the option to add a service reference. You will probably need to remove "Xamarin Forms" from your project and then replace it (using Nuget package manager) before you can do this though. Also, when you add the service reference, make sure you go to the 'advanced' options and clear the 'Reuse types' checkbox, as this causes VS2015 to crash.

Dominic
Comment by Sandhya

I have followed all the steps which have mentioned. But when I try to add service reference I get a message 'This service cannot be consumed by the current project. Please check if the project target framework supports this service type.' Please let me know how to resolve this issue.

Sandhya
Comment by Mark

@Sandhya sorry to hear it did not work out. To what kind of a project are you adding the service reference and in case of a PCL, which platforms are you targeting?

Post comment