Over a million developers have joined DZone.

Consuming OData for TFS Using C# from Windows Phone 7 Application

· Mobile Zone

Visually compose APIs with easy-to-use tooling. Learn how IBM API Connect provides near-universal access to data and services both on-premises and in the cloud, brought to you in partnership with IBM.

In the earlier post we saw how to consume the OData service from console application. The same code applies for any desktop application, whether it is Windows Forms or WPF application. Since there is no support for developing WP7 applications in the Visual Studio 11 Beta, the code is written in the Visual Studio 2010 Express for Windows Phone.

Add the reference to the OData service using the instructions from the last post.

Authorization

Authorization is slightly different. Here is a complete code:

// context is a valid instance of the TFSData class
context.SendingRequest += (s, e) =>
{
    var credentials = string.Format(@"{0}\{1}:{2}", "DOMAIN", "USERNAME", "PASSWORD");
    e.RequestHeaders["Authorization"] = string.Format(CultureInfo.InvariantCulture, "Basic {0}", Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(credentials)));
};

Resource access problem

Even though you could use the same code for accessing the service’s resources on the desktop regardless of the application type, some parts of the code cannot be used on the Windows Phone 7.

For example, the following code will not work out of the box:

class TFSServiceHelper
{
    public IEnumerable<string> GetProjectNames()
    {
        // TFSService is a valid instance of the TFSData class
        return this.TFSService.Projects.Select(item => item.Name);
    }
}
 
// somewhere else, helper is an instance of the TFSServiceHelper class
foreach (var projectName in helper.GetProjectNames)
    _projects.Add(projectName);

You will get a NotSupportedException with the following details:

Silverlight does not enable you to directly enumerate over a data service query. This is because enumeration automatically sends a synchronous request to the data service. Because Silverlight only supports asynchronous operations, you must instead call the BeginExecute and EndExecute methods to obtain a query result that supports enumeration.


Asynchronous version

Since it is expected of WP7 apps to never block the UI, you are forced to write the same code asynchronously using the BeginExecute/EndExecute methods. While this is not such a hard task, it is cumbersome to write all that boilerplate code for something that is essentially a one liner. Correct version of the above code is:

// async version of GetProjectNames
public IAsyncResult GetProjectNamesAsync(Action<IEnumerable<string>> callback)
{
    return this.TFSService.Projects.BeginExecute((ar) =>
    {
        var results = this.TFSService.Projects.EndExecute(ar);
        Deployment.Current.Dispatcher.BeginInvoke(() => callback(results.Select(item => item.Name)));
    }, null);
}
 
// usage
helper.GetProjectNamesAsync((names) =>
{
    foreach (var projectName in names)
        _projects.Add(projectName);
});

Our very simple application as it appears in the emulator:


Using C# 5 style asynchrony

The above code is correct, but it breaks the code flow. We want both the power and necessity of the asynchronous version while at the same time the elegance of the synchronous version. In the previous post we saw how to use the new feature in the VS11 for streamlined asynchronous syntax. However, we cannot do the same in WP7 since Visual Studio 2010 Express for Windows Phone does not use the same C# compiler the VS11 is using.

Luckily, the solution is simple: download and install Visual Studio Async CTP (Version 3) and you will be able to use async/await in the WP7 applications. Simply add the reference to the AsyncCtpLibrary_Phone assembly (you can find it in the \Documents\Microsoft Visual Studio Async CTP\Samples folder) and write code using it.

Asynchronous version of the GetProjectNames function:

public async Task<IEnumerable<string>> GetProjectNamesTaskAsync()
{
    return (await this.TFSService.Projects.ExecuteAsync(null)).Select(item => item.Name);
}

You can use the above function by adding a minimum amount of code to the first, and erroneous, sample at the beginning of this post:

foreach (var projectName in await helper.GetProjectNamesTaskAsync())
    _projects.Add(projectName)

However, this will not immediately compile, we must add the same extension method from the previous post.

Conclusion

That is it, you can now write your OData client for Windows Phone 7. If you are lucky and you can use Async CTP, the code will be pleasant to write while the UI will remain fluent and responsive.

In the next post we will see how to create and update resources using OData Service for TFS.

The Mobile Zone is brought to you in partnership with Strongloop and IBM.  Visually compose APIs with easy-to-use tooling. Learn how IBM API Connect provides near-universal access to data and services both on-premises and in the cloud.

Topics:

Published at DZone with permission of Toni Petrina, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}