Walkthrough: OData client for Windows Live Services

Background

As described recently on the Windows Live team blog, programming against your Windows Live artifacts (Calendar, Photos, etc) is now possible using OData. This blog post will walk through how to use our recently released WCF Data Services CTP to interact with the Windows Live OData endpoint.

In general the Windows Live OData endpoint is just like any other OData endpoint so the good news is you already pretty much know how to use it J. This post will cover the basics of using some of the new features in our latest WCF Data Services CTP and some of the Windows Live specific aspects you need to know such as:

· Security: The Windows Live OData endpoint uses OAuth for security, as such requires the user to sign in with their windows live account before any operation against the user’s data (contacts, photos etc.) can be done.

· Different base addresses for Collections: In other words your Contacts & Photos data may not share a common base URI as can be seen in the snippet below from the Windows Live OData endpoint Service Document. We’ve added a new feature in this CTP called an “Entity Set Resolver” (which we’ll go describe in detail in a subsequent blog post) that makes it easy to work with partitioned collection in an OData service:

<service xmlns:xml="https://www.w3.org/XML/1998/namespace" xmlns:atom="https://www.w3.org/2005/Atom" xmlns="https://www.w3.org/2007/app">

<workspace xml:base="https://apis.live.net/V4.1/">

<collection href="https://contacts.apis.live.net/V4.1/ ">

<atom:title name="text">Contacts</atom:title>

<accept>application/atomsvc+xml</accept>

<accept>application/json</accept>

<accept>text/xml</accept>

<accept>binary/xml</accept>

<categories fixed="no"/>

</collection>

<collection href="https://photos.apis.live.net/V4.1/">

<atom:title name="text">Photos</atom:title>

<accept>application/atomsvc+xml</accept>

<accept>application/json</accept>

<accept>text/xml</accept>

<accept>binary/xml</accept>

<categories fixed="no"/>

</collection>

</workspace>

</service>

Listing: Sample Live Service Document

Walkthrough

Lets walkthrough the sequence of steps needed to create a simple application that displays albums & the photos associated with those albums for a given user. Please note that all files referenced in the in this post are part of the attached Visual Studio solution.

1. To retrieve the authentication token for a given user refer to the live blog post here to get the code needed to produce the sign in window, using the appropriate Client Application ID, Client Secret key live application information and auth token.

2. To get a Client Application ID and Client key tied to your Live user account please visit manage.dev.live.com. In the attached sample they are specified in the LiveDataServiceContext partial class, in the clientId & clientSecret fields. You will need to replace the values of these fields with the ones tied to your Live account.

3. To integrate the sign in process and auth token retrieval with the construction of a DataServiceContext class, please, see LiveDataServiceContext.cs:

partial void OnContextCreated()

{

messengerConnectSigninHelper = new MessengerConnectSigninHelper();

messengerConnectSigninHelper.SignInCompleted += new MessengerConnectSigninHelper.SignInCompletedEventHandler(SignInCompletedEventHandler);

messengerConnectSigninHelper.GetTokenAsync(LiveApplicationInformation, null);

}

void SignInCompletedEventHandler(SignInCompletedEventArgs e)

{

this.AuthToken = messengerConnectSigninHelper.AuthorizationToken;

this.entitySetResolver.ParseServiceDocumentComplete += new ParseServiceDocumentComplete(EntitySetResolver_ParseServiceDocumentComplete);

this.entitySetResolver.GetBaseUrisFromServiceDocumentAsync(this.BaseUri);

}

At this point the user is signed in & we have the Auth token to use in subsequent requests.

4. The next order of business is to retrieve the Live Service Document so that we can retrieve the base URIs for all the collections (Photos, Albums, etc) exposed by the OData service. This step is required because the collections in the Windows Live OData service are partitioned and available from different base URIs. Refer to LiveEntitySetResolver.GetBaseUrisFromServiceDocumentAsync() in the attached project for details.

5. Now that we have base URIs for every collection (Albums, Photos, etc) described by the Service Document we need to register a delegate with the DataServiceContext that will be invoked each time the Data Services client needs the base URI for a Collection. Refer to the LiveEntitySetResolver constructor for details:

ctx.ResolveEntitySet = this.ESR; // hook up the “Entity Set Resolver”

6. To include the authentication token retrieved from setup 1 in subsequent requests to the OData service you need to register a SendingRequest event handler with the data services context:

dataServicesctx.SendingRequest += new EventHandler<SendingRequestEventArgs>(context_SendingRequest);

Before every request the authorization header needs to be included in the request:

public void context_SendingRequest(object sender, SendingRequestEventArgs e)

{

e.RequestHeaders[MessengerConnectConstants.AuthorizationHeader] = authToken;

}

7. At this point the DataServiceContext is ready to use to retrieve albums & photos. For example, the snippet from MainPage.liveCtx_Initalized() below uses the DataServiceContext to execute a LINQ query to retrieve non empty Albums.

albumQuery = new DataServiceCollection<Album>(liveCtx);

var query = from p in liveCtx.Albums

where p.Size > 0

select p;

albumQuery.LoadCompleted += new EventHandler<LoadCompletedEventArgs>(dsc_LoadCompleted);

albumQuery.LoadAsync(query);

8. Given that a metadata endpoint is not yet available for the Windows Live OData endpoint the easiest way to get started is to reuse the types (Album, Photo, etc) in the attached sample project. Once the metadata endpoint is up and running you will be able to generate the client types by using the “Add Service Reference” gesture in Visual Studio or the DataSvcUtil.exe command line tool just as you would with any OData metadata endpoint.

Ahmed Moustafa

Program Manager, Microsoft

LiveFxSLApp.zip