Consuming OData for TFS Using C# from Windows Phone 7 Application
Join the DZone community and get the full member experience.
Join For FreeIn 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.
Published at DZone with permission of Toni Petrina, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments