Introduction
This is part II to the previous clog (http://openlightgroup.net/Blog/tabid/58/EntryId/98/OData-Simplified.aspx) where we looked at a simple OData example. This time, we will make a simple Silverlight application that talks to an oData service.
Note, for this tutorial, you will also need to download and install RX Extensions from: http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx, and the Silverlight Toolkit from: http://silverlight.codeplex.com.
As with the last tutorial, we will not use a database, just a simple collection that we are creating programmatically. This will allow you to see just the oData parts.
First, open up the project, in Visual Studio 2010 (or higher), from the zip file at the bottom of this link.
Select Add, then New Project...
Create a new Silverlight Application.
Add a Service Reference.
Click Discover.
Create a reference called wsSampleCustomerData.
Next, add assembly references in your Silverlight project to:
System.CoreEx
System.Observable
System.Reactive
In the Silverlight project, delete the MainPage.xaml.
Open the project in Expression Blend 4 (or higher).
In Expression Blend, select File then New Item...
Select the UserControl with ViewModel template, and create a file called MainPage.xaml.
It will create the ViewModel pages (MainPage.xaml and MainPage.xaml.cs with a MainPageModel.cs View Model page that is already wired-up).
Create a folder called Model and a class called Model.cs.
Replace all the code with the following code:
using System;
using System.Linq;
using System.Collections.Generic;
using SilverlightODataSample.wsSampleCustomerData;
using System.Data.Services.Client;
namespace SilverlightODataSample
{
public class Model
{
#region GetCustomers
public static IObservable < IEvent < LoadCompletedEventArgs> >
GetCustomers(int intPage)
{
Uri objUri = new Uri(GetBaseAddress(), UriKind.RelativeOrAbsolute);
SampleDataSource SDS = new SampleDataSource(objUri);
var query = (from SampleCustomerData in SDS.SampleCustomerData
where SampleCustomerData.CustomerNotes.Contains("3")
select SampleCustomerData).Skip(intPage).Take(10);
DataServiceCollection< CustomerRecord > CustomerRecords =
new DataServiceCollection< CustomerRecord >();
IObservable< IEvent < LoadCompletedEventArgs> > observable =
Observable.FromEvent< LoadCompletedEventArgs >(CustomerRecords,
"LoadCompleted");
CustomerRecords.LoadAsync(query);
return observable;
}
#endregion
#region GetBaseAddress
private static string GetBaseAddress()
{
string strXapFile = @"/ClientBin/SilverlightODataSample.xap";
string strBaseWebAddress =
App.Current.Host.Source.AbsoluteUri.Replace(strXapFile, "");
return string.Format(@"{0}/{1}", strBaseWebAddress, @"Service.svc");
}
#endregion
}
}
Open MainPageModel.cs and replace all the code with the following code:
using System;
using System.ComponentModel;
using System.Collections.ObjectModel;
using SilverlightODataSample.wsSampleCustomerData;
using System.Data.Services.Client;
namespace SilverlightODataSample
{
public class MainPageModel : INotifyPropertyChanged
{
public MainPageModel()
{
GetCustomers();
}
#region GetCustomers
private void GetCustomers()
{
Model.GetCustomers(0).Subscribe(p = >
{
if (p.EventArgs.Error == null)
{
foreach (CustomerRecord Customer in
(DataServiceCollection< CustomerRecord >)p.Sender)
{
colCustomerRecord.Add(Customer);
}
}
});
}
#endregion
#region CustomerRecord
private ObservableCollection< CustomerRecord > _colCustomerRecord
= new ObservableCollection< CustomerRecord >();
public ObservableCollection< CustomerRecord > colCustomerRecord
{
get { return _colCustomerRecord; }
private set
{
if (colCustomerRecord == value)
{
return;
}
_colCustomerRecord = value;
this.NotifyPropertyChanged("colCustomerRecord");
}
}
#endregion
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
#endregion
}
}
Grab a DataGrid
and drop it on the design surface.
Widen it so it fills the page.
Click on the Data tab so that you see the Data Context.
Drag and drop the colCustomerRecord
collection onto the DataGrid
.
Build and run the project.
OData and RX extensions are pretty impressive:
- RX extensions were used because it decouples the oData Service calls from the View Model. This allows the methods in the model to be easily called by multiple View Models.
- We are only grabbing the first page of the results, but we could easily implement paging by passing the page number to the method.
- We are also only creating a simple query. We could easily create a more complex query of the oData Service.
Security
For information on securing your OData Methods, see: Simple Example to Secure WCF Data Service OData Methods.