How to: Consume an OData Service for Windows Phone
March 23, 2012
This topic describes how to consume an Open Data Protocol (OData) feed in a Windows Phone application using the OData client library for Windows Phone.
The OData client library for Windows Phone generates HTTP requests to a data service that supports OData and transforms the entries in the response feed into objects on the client. Using this client, you can bind Windows Phone controls, such as Listbox or Textbox, to an instance of a DataServiceCollection<T> class that contains an OData data feed. This class handles the events raised by the controls to keep the DataServiceContext class synchronized with changes that are made to data in the controls. For more information about using the OData protocol with Windows Phone applications, see Open Data Protocol (OData) Client for Windows Phone.
A query determines which data objects the DataServiceCollection<T> class will contain. This query is specified as either a DataServiceQuery<TElement>, which supports Language Integrated Query (LINQ), or a uniform resource identifier (URI). The query is specified as a parameter in the LoadAsync(IQueryable<T>) method of the DataServiceCollection<T> class. When executed, this method returns an OData feed that is materialized into data objects in the collection. Data from the collection is displayed by controls when this collection is the binding source for the controls. For more information about querying an OData service by using URIs, see the OData: URI Conventions page at the OData Web site.
The procedures in this topic show how to perform the following tasks:
Create a new Windows Phone application.
Add a data service reference to the project.
Query the OData service and bind the results to controls in the application.
Note: |
|---|
This example demonstrates basic data binding to a single page in a Windows Phone application by using a DataServiceCollection<T> binding collection. For information about how to persist and restore application data in this application during state changes that might occur during execution, see How to: Persist the State of an OData Client for Windows Phone. For an example of a multi-page Windows Phone application that uses the Model-View-ViewModel (MVVM) design pattern and also maintains state during execution, see Walkthrough: Consuming OData with MVVM for Windows Phone. |
This example uses the Northwind sample data service that is published on the OData Web site. This sample data service is read-only; attempting to save changes will return an error.
To create the Windows Phone application
In Solution Explorer, right-click the Solution, point to Add, and then select New Project.
In the Add New Project dialog box, select Silverlight for Windows Phone from the Installed Templates pane, and then select the Windows Phone Application template. Name the project ODataNorthwindPhone.
In the New Windows Phone Application dialog box, select Windows Phone 7.1 in the Target Windows Phone Version drop-down box.
Click OK. This creates the application for Silverlight.
To add a data service reference to the project
Right-click the ODataNorthwindPhone project, click Add Service Reference.
This displays the Add Service Reference dialog box.
In the Address text box, enter the following URI value and then click Go:
http://services.odata.org/Northwind/Northwind.svc/
This downloads the metadata document from the public, read-only Northwind sample data service.
In the Namespace text box, type Northwind, and then click OK.
This adds a new code file to the project, which contains the data classes that are used to access and interact with data service resources as objects. The data classes are created in the namespace ODataNorthwindPhone.Northwind. A reference to the System.Data.Services.Client.dll assembly is also added.
To define the Windows Phone application user interface
In the project, double-click the MainPage.xaml file.
This opens XAML markup for the MainPage class that is the user interface for the Windows Phone application.
Replace the existing XAML markup with the following markup that defines the user interface for the main page that displays customer information.
<phone:PhoneApplicationPage x:Class="ODataNorthwindPhone.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:my="clr-namespace:ODataNorthwindPhone.Northwind" mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768" d:DataContext="{d:DesignInstance Type=my:Customer, CreateList=True}" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" shell:SystemTray.IsVisible="True" Loaded="MainPage_Loaded"> <Grid x:Name="LayoutRoot" Background="Transparent"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28"> <TextBlock x:Name="ApplicationTitle" Text="Northwind Sales" Style="{StaticResource PhoneTextNormalStyle}"/> <TextBlock x:Name="PageTitle" Text="Customers" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/> </StackPanel> <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <ListBox x:Name="MainListBox" Margin="0,0,-12,0" ItemsSource="{Binding}"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Margin="0,0,0,17" Width="432"> <TextBlock Text="{Binding Path=CompanyName}" TextWrapping="NoWrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/> <TextBlock Text="{Binding Path=ContactName}" TextWrapping="NoWrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/> <TextBlock Text="{Binding Path=Phone}" TextWrapping="NoWrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </Grid> </Grid> </phone:PhoneApplicationPage>
To add the code that binds data service data to controls in the Windows Phone application
In the project, open the code page for the MainPage.xaml file, and add the following using statements:
using System.Data.Services.Client; using ODataNorthwindPhone.Northwind;
Add the following declarations to the MainPage class:
// Declare the data service objects and URIs. private NorthwindEntities context; private readonly Uri northwindUri = new Uri("http://services.odata.org/Northwind/Northwind.svc/"); private DataServiceCollection<Customer> customers;Add the following MainPage_Loaded method to the MainPage class:
private void MainPage_Loaded(object sender, RoutedEventArgs e) { // Initialize the context and the binding collection context = new NorthwindEntities(northwindUri); customers = new DataServiceCollection<Customer>(context); // Define a LINQ query that returns all customers. var query = from cust in context.Customers select cust; // Register for the LoadCompleted event. customers.LoadCompleted += new EventHandler<LoadCompletedEventArgs>(customers_LoadCompleted); // Load the customers feed by executing the LINQ query. customers.LoadAsync(query); }When the page is loaded, this code initializes the binding collection and content, and registers the method to handle the LoadCompleted event of the DataServiceCollection<T> object, raised by the binding collection.
Add the following customers_LoadCompleted method to the MainPage class:
void customers_LoadCompleted(object sender, LoadCompletedEventArgs e) { if (e.Error == null) { // Handling for a paged data feed. if (customers.Continuation != null) { // Automatically load the next page. customers.LoadNextPartialSetAsync(); } else { // Set the data context of the list box control to the sample data. this.LayoutRoot.DataContext = customers; } } else { MessageBox.Show(string.Format("An error has occurred: {0}", e.Error.Message)); } }When the LoadCompleted event is handled, the following operations are performed if the request returns successfully:
The LoadNextPartialSetAsync() method of the DataServiceCollection<T> object is called to load subsequent results pages, as long as the Continuation property of the DataServiceCollection<T> object returns a value.
The collection of loaded Customer objects is bound to the DataContext property of the element that is the master binding object for all controls in the page.
For information about how to persist and restore application data during state changes that might occur during execution, see How to: Persist the State of an OData Client for Windows Phone.
Note: