Click here to Skip to main content
Click here to Skip to main content

Simple Silverlight 4 Example Using oData and RX Extensions

, 23 May 2010
Rate this:
Please Sign up or sign in to vote.
A simple Silverlight application that uses RX Extensions to communicate with an oData service.

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)
        {
            // Create a URI that points to the OData Service
            Uri objUri = new Uri(GetBaseAddress(), UriKind.RelativeOrAbsolute);

            // Set up oData service call
            SampleDataSource SDS = new SampleDataSource(objUri);

            // Construct a Query
            var query = (from SampleCustomerData in SDS.SampleCustomerData
                         where SampleCustomerData.CustomerNotes.Contains("3")
                         select SampleCustomerData).Skip(intPage).Take(10);

            // Set up a DataServiceCollection to hold the results
            DataServiceCollection< CustomerRecord > CustomerRecords = 
                new DataServiceCollection< CustomerRecord >();

            // Set up a Rx Observable (in a variable called observable) 
            // that will contain the results of
            // the "LoadCompleted" event that CustomerRecords will fire
            // When LoadAsync(query) is fired in the following statement
            IObservable< IEvent < LoadCompletedEventArgs> > observable =
                Observable.FromEvent< LoadCompletedEventArgs >(CustomerRecords,
                "LoadCompleted");

            // Execute the LoadAsync on CustomerRecords passing
            // the query that was constructed earlier
            CustomerRecords.LoadAsync(query);

            // Return observable
            return observable;
        }
        #endregion

        #region GetBaseAddress
        private static string GetBaseAddress()
        {
            // This gets the address of the webservice by 
            // getting the AbsoluteUri and then stripping out the 
            // name of the .xap file
            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()
        {
            // When the Control loads
            // Get the Customers
            GetCustomers();
        }

        #region GetCustomers
        private void GetCustomers()
        {
            // Call the Model to get the Customers
            // Passing in 0 to get the first page
            // Paging could easily be done here
            // You could also pass in other criteria
            Model.GetCustomers(0).Subscribe(p = >
            {
                // Check for an error in the Service
                if (p.EventArgs.Error == null)
                {
                    // loop thru each item in the
                    // DataServiceCollection< CustomerRecord >
                    // Collection
                    foreach (CustomerRecord Customer in
                        (DataServiceCollection< CustomerRecord >)p.Sender)
                    {
                        // Add to the Customer to the colCustomerRecord 
                        // Collection so the View can bind to it
                        colCustomerRecord.Add(Customer);
                    }
                }
            });

        }
        #endregion

        #region CustomerRecord
        // The View will bind to this collection and automatically be notified if 
        // The collection changes. The Designer can bind any UI element that 
        // can hold a collection
        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
        // This is a supporting method to raise a notification for any
        // Element that is subscribed to a Property that implements
        // NotifyPropertyChanged
        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.

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)

About the Author

defwebserver
Software Developer (Senior) http://ADefWebserver.com
United States United States
Michael Washington is a Microsoft MVP. He is a ASP.NET and C# programmer.
 
He is the founder of http://LightSwitchHelpWebsite.com
 
He has a son, Zachary and resides in Los Angeles with his wife Valerie.
Follow on   Twitter

Comments and Discussions

 
GeneralMy vote of 5 PinmemberMember 96405625-Dec-12 0:19 
GeneralAnother excellent article! Pinmembermbcrump8-Feb-11 16:09 
GeneralRe: Another excellent article! Pinmvpdefwebserver8-Feb-11 17:44 
GeneralGood article, but I don't think you are using RX Extensions 100% correctly... Pinmemberaemami9924-May-10 13:50 
GeneralRe: Good article, but I don't think you are using RX Extensions 100% correctly... Pinmemberdefwebserver24-May-10 14:01 
GeneralRe: Good article, but I don't think you are using RX Extensions 100% correctly... Pinmemberaemami9924-May-10 14:51 
GeneralRe: Good article, but I don't think you are using RX Extensions 100% correctly... Pinmemberdefwebserver24-May-10 15:23 
GeneralRe: Good article, but I don't think you are using RX Extensions 100% correctly... Pinmemberaemami9924-May-10 15:53 
GeneralRe: Good article, but I don't think you are using RX Extensions 100% correctly... Pinmemberdefwebserver25-May-10 13:33 
GeneralRe: Good article, but I don't think you are using RX Extensions 100% correctly... Pinmemberaemami9925-May-10 14:08 
GeneralNice Article Pinmemberlinuxjr23-May-10 14:49 
GeneralRe: Nice Article Pinmemberdefwebserver23-May-10 15:57 
GeneralGood one.. PinmemberRajesh Pillai21-May-10 3:58 
GeneralRe: Good one.. Pinmemberdefwebserver21-May-10 4:52 
GeneralThis is nice, though PinmvpSacha Barber20-May-10 21:52 
GeneralRe: This is nice, though [modified] Pinmemberdefwebserver21-May-10 1:50 
GeneralRe: This is nice, though PinmvpSacha Barber21-May-10 3:16 
GeneralRX Extensions? - Is that like dreadlocks or something??? :-) PinmemberAlan Beasley20-May-10 6:09 
GeneralRe: RX Extensions? - Is that like dreadlocks or something??? :-) Pinmemberdefwebserver20-May-10 7:39 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140721.1 | Last Updated 23 May 2010
Article Copyright 2010 by defwebserver
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid