Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

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

DZone's Guide to

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

· Mobile Zone
Free Resource

Discover how to focus on operators for Reactive Programming and how they are essential to react to data in your application.  Brought to you in partnership with Wakanda

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.

Learn how divergent branches can appear in your repository and how to better understand why they are called “branches".  Brought to you in partnership with Wakanda

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 DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

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

X

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

{{ parent.tldr }}

{{ parent.urlSource.name }}