Share via


Exercise 3: Building a Silverlight Client with OData Feeds

In this exercise, you will create a Silverlight Application that consumes a local OData service and an OData service on the clouds. Additionally, this exercise demonstrates how to perform simple CRUD operations using LINQ.

Task 1 – Creating Silverlight Application

  1. In this task, you will create the Silverlight client application, which exposes products for the categories available in each shopping center.
  2. Open Microsoft Visual Studio 2010, from Start | All Programs | Microsoft Visual Studio 2010. If the User Account Control dialog appears, click Continue.
  3. In the File menu, choose Open and then Project/Solution. In the Open Project dialog, browse to Ex3\Begin in the Source folder of the lab, select OpenDataService.sln in the folder of the language of your preference (Visual C# or Visual Basic), and click Open.

    Note:
    If you performed the previous exercise, you can use the same ending solution.

  4. The solution contains the following project:

    Figure 15

    Solution Explorer showing the Open Data solution

    WebSite

    A standard web site project that hosts the AdventureWorks service and expose its entities.

  5. In the Solution Explorer, right-click the solution, select Add | New Project. In the New Project dialog, expand the language of your preference (Visual C# or Visual Basic) in the Project types list select Silverlight. In the Templates list, select Silverlight Application. Enter the name AdventureWorksShopping, and click OK to create the project.

    Figure 16

    Creating a new Silverlight Application project (C#)

    Figure 17

    Creating a new Silverlight Application project (VB)

  6. In the New Silverlight Application dialog, make sure that the WebSite project is selected to host the Silverlight application, and that the Silverlight 4 version of the framework is targeted. Make sure that the Add a test page references the application checkbox, and click OK.

    Figure 18

    New Silverlight Application Dialog

    The following figure shows the newly Silverlight Application in the Solution Explorer.

    Figure 19

    Solution Explorer Showing the Adventure Works Shopping project (C#)

    Figure 20

    Solution Explorer Showing the Adventure Works Shopping project (VB)

Task 2 – Adding Service References

This exercise uses the Open Government Data Initiative (OGDI) databases. OGDI uses the Windows Azure Platform to make it easier to publish and use a wide variety of public data from government agencies. OGDI is also a free, open source starter kit, which includes code that can be used to publish data on the Internet in a Web-friendly format with easy-to-use, open API's. OGDI-based web API’s can be accessed from a variety of client technologies such as Silverlight, Flash, JavaScript, PHP, Python, Ruby, mapping web sites, etc.

In this task, you will create a reference to the Open Government Data Initiative (OGDI) and a reference to the Adventure Works service.

  1. Add the OGDI reference to the AdventureWorksShopping project. To do this, in Solution Explorer, right-click the AdventureWorksShopping project, and select Add Service Reference.
  2. Enter https://ogdi.cloudapp.net/v1/dc as the Address, and click Go to search for services. Visual Studio will find and show the available services.
  3. Set the Namespace to DistrictOfColumbia, and click OK to add the service reference.

    Figure 21

    Adding the Service Reference

  4. To add the Adventure Work reference into the project, run the ASP.NET applications locally in the ASP.NET Development Server. To do this, in the Solution Explorer, right-click the AdventureWorks.svc file of the WebSite project and click View in Browser.

    Note:
    Notice that the Adventure Work service is configured to use the port number 50000. Make sure there is no other application that uses this port. If you wish, you can change the Web properties of the project.

    Figure 22

    ASP.NET Development Server Showing the Adventure Work host service

  5. Add the AdventureWorks reference to the project. To do this, in the Solution Explorer, right-click the AdventureWorksShopping project, and click Add Service Reference.
  6. Enter https://localhost:50000/AdventureWorks.svc as the Address, and click Go to search for services. Visual Studio will find and show the available services.
  7. Set the Namespace to AdventureWorks, and click OK to add the service reference.

    Figure 23

    Solution Explorer showing the Service Reference into the AdventureWorksShopping project

Task 3 – Configuring the AdventureWorks Shopping Project

In this task, you will complete the methods that query the database to retrieve the application data. All the queries use LINQ.

  1. Delete the MainPage.xaml file from the AdventureWorks. To do this, in the Solution Explorer, right-click the file and click Delete.
  2. Right-click the AdventureWorksShopping project, point to Add, and click Existing Item. Browse to the Source\Assets\Ex3\ folder, go to the subfolder that corresponds to the language of your preference, select the MainPage.xaml file, and click Add.

    If the AdventureWorks.svc service is running on a different port than 50000, you need to change the service URL in the AdventureWorks property of the MainPage class.

    Figure 24

    Configuring the AdventureWorks service URL

  3. Add the file that contains the styles of the application’s UI. To do this, right-click the AdventureWorksShopping project, point to Add, click New Folder and name it Styles. Right-click this folder, point to Add and click Existing Item. Browse to the Source\Assets\Ex3\ folder, select the Styles.xaml file, and click Add.
  4. Add a reference to the styles file in App.xaml. To do this, open App.xaml and add the following code, between the Application.Resources tags.

    XAML

    <Application.Resources>
    <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Styles/styles.xaml"></ResourceDictionary> </ResourceDictionary.MergedDictionaries> </ResourceDictionary>FakePre-3e8b0f079d594b1f9bc1e29ef04617d5-837197e9646f41ec9cb8c62ef2e84995

  5. Add the following references to the AdventureWorksShopping by right-clicking the References folder in Solution Explorer, and clicking Add Reference.
    • System.Windows.Controls.Data
    • System.Windows.Controls.Data.Input
  6. Select the MainPage.xaml file in Solution Explorer, and press F7 to open its code file.
  7. Check the AdventureWorks and DistrictOfColumbia properties; both initialize their respective data services in their getters.
  8. Locate the UserControl_Loaded method and add the following code.

    (Code Snippet – OData Lab - Ex 3.3.8 UserControl_Loaded Method - CS)

    C#

    private void UserControl_Loaded(object sender, RoutedEventArgs e)
    FakePre-f61502cbf01e4c6388fcb8d218f95b46-f5db75513545454db7171cdbddbfa33c var categoryQuery = (from category in this.AdventureWorks.ProductCategory.Expand("ProductCategoryShopping") where category.ParentProductCategoryID != null select category) as DataServiceQuery<ProductCategory>; this.AsyncQueryOnDataContext(categoryQuery, this.CategoriesListbox); var shoppingCartQuery = this.AdventureWorks.ShoppingCart.Expand("Product"); this.AsyncQueryOnDataContext(shoppingCartQuery, this.ShoppingCartListbox);FakePre-3b223869124642a4b7cf24d717dc5b24-43195e957d1a4460bf2086f46b6a476eFakePre-b3d3398835bd41bea77228fad9d651b2-39fb301b7ab2458eb0731e39fa9fdb98

    (Code Snippet – ODataLab - Ex 3.3.8 UserControl_Loaded Method - VB)

    Visual Basic

    Private Sub UserControl_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
    Dim categoryQuery = TryCast((From category In Me.AdventureWorks.ProductCategory.Expand("ProductCategoryShopping") _ Where category.ParentProductCategoryID IsNot Nothing _ Select category), DataServiceQuery(Of ProductCategory)) Me.AsyncQueryOnDataContext(categoryQuery, Me.CategoriesListbox) Dim shoppingCartQuery = Me.AdventureWorks.ShoppingCart.Expand("Product") Me.AsyncQueryOnDataContext(shoppingCartQuery, Me.ShoppingCartListbox)FakePre-a72798f18f084e3698abe54b8aebf6da-e63c3bdf30aa401098389f034e10500fFakePre-6d86011835c24f5c878db0cbe270af51-f4ec855a3e46430ca6e1082fd86c18e2

    The preceding method queries the AdventureWorks service and retrieves the data necessary to populate the list boxes of the application when it is loaded.

  9. Locate the CategoriesListBox_SelectionChanged method, which updates the list of products when a category is selected, and add the following code.

    (Code Snippet – OData Lab - Ex 3.3.9 CategoriesListBox_SelectionChanged Method - CS)

    C#

    private void CategoriesListbox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    FakePre-2f4ae57ebbd74212bd6f081306e8b493-7185e7a590d64af58ce5691148ec9ae3 var category = this.CategoriesListbox.SelectedItem as ProductCategory; PopulateFilteredShoppingCenters(category); this.AdventureWorks.BeginLoadProperty( category, "Product", result => this.Dispatcher.BeginInvoke(() => { this.AdventureWorks.EndLoadProperty(result); this.ProductsListbox.DataContext = category.Product; }), null);FakePre-7841e3567b554097bc4efda3479a9adc-87b1b2de655546599bc17890f7c3d2b6FakePre-f9118fb257684bbe8c31a1fca4026717-d7334f6c291442139e33fcfe73a02ed6

    (Code Snippet – OData Lab - Ex 3.3.9 CategoriesListBox_SelectionChanged Method - VB)

    Visual Basic

    Private Sub CategoriesListbox_SelectionChanged(ByVal sender As Object, ByVal e As SelectionChangedEventArgs)
    Dim category = TryCast(Me.CategoriesListbox.SelectedItem, ProductCategory) PopulateFilteredShoppingCenters(category) Me.AdventureWorks.BeginLoadProperty(category, "Product", Sub(result) Me.Dispatcher.BeginInvoke(Sub() Me.AdventureWorks.EndLoadProperty(result) Me.ProductsListbox.DataContext = category.Product End Sub) End Sub, Nothing)FakePre-87671deda92448c38c06cda0970593b3-91d5219a49f3493cbc2e04acca5117a3FakePre-ac35587dfedc486aa34cbd72a45af0a2-065841f890d540c1b01144beadc7216e

  10. Locate the PopulateFilteredShoppingCenters method and add the following code. This method creates a filter to return only the shopping centers that sell the specified product category.

    (Code Snippet – ODataLab - Ex 3.3.10PopulateFilteredShoppingCentersMethod - CS)

    C#

    private void PopulateFilteredShoppingCenters(ProductCategory category)
    FakePre-6cb7e7fb64e34da7a06dfe9e325058f1-def667e95e344f83abbf5e444d0d6919 if (category != null && category.ProductCategoryShopping != null && category.ProductCategoryShopping.Count > 0) { var shoppingQuery = (from shoppingCenter in this.DistrictOfColumbia.ShopingCenters.AddQueryOption("$filter", this.CreateShoppingsFilter(category)) select shoppingCenter) as DataServiceQuery<ShopingCenter>; this.AsyncQueryOnDataContext(shoppingQuery, this.ShoppingsListbox); } else { this.ShoppingsListbox.DataContext = null; }FakePre-84356798656a4f26a9facc37760a6491-9e028e7d3d544631b680013bd78d77c5FakePre-aa700b1818d8412c83582c8e9d5127e3-4b947dd38b49456190cb9e3acc2ef959

    (Code Snippet – ODataLab - Ex 3.3.10PopulateFilteredShoppingCentersMethod - VB)

    Visual Basic

    Private Sub PopulateFilteredShoppingCenters(ByVal category As ProductCategory)
    If category IsNot Nothing AndAlso category.ProductCategoryShopping IsNot Nothing AndAlso category.ProductCategoryShopping.Count > 0 Then Dim shoppingQuery = TryCast((From shoppingCenter In Me.DistrictOfColumbia.ShopingCenters.AddQueryOption("$filter", Me.CreateShoppingsFilter(category)) _ Select shoppingCenter), DataServiceQuery(Of ShopingCenter)) Me.AsyncQueryOnDataContext(shoppingQuery, Me.ShoppingsListbox) Else Me.ShoppingsListbox.DataContext = Nothing End IfFakePre-6b695a4cfad54859ba5ec64d26606094-31128711a8a84829b4e1db3df43871f7FakePre-c8abc2768c1145c9a272d9577f00f86e-4697f36577634968939a0b01c6b7f706

  11. Press CTRL+SHIFT+B to build the solution.

Task 4 – Persisting Changes to a Database

In this task, you will complete the methods that manage the shopping cart and save its content to the database.

  1. In the MainPage.xaml.cs file, locate the AddItemButton_Click method and add the following code. This method adds one unit of the corresponding product to the shopping cart.

    (Code Snippet – ODataLab - Ex 3.4.1AddItemButton_ClickMethod - CS)

    C#

    private void AddItemButton_Click(object sender, RoutedEventArgs e)
    FakePre-36281a33b38c4d609ffdbff632f4127b-5a704c9bc4854e96a31dd01b3f22165b var product = ((Button)sender).DataContext as Product; if (product != null) { var shoppingCart = this.ShoppingCartListbox.DataContext as ObservableCollection<ShoppingCart>; var item = shoppingCart.SingleOrDefault(i => i.ProductID == product.ProductID); if (item == null) { var newShoppingCart = new ShoppingCart { ProductID = product.ProductID, Product = product, ItemQty = 1 }; shoppingCart.Add(newShoppingCart); this.AdventureWorks.AddToShoppingCart(newShoppingCart); } else { item.ItemQty++; this.AdventureWorks.UpdateObject(item); } }FakePre-ed140035402147fcbd4388b68af35eb2-58b7fe27c9854fd895fe90d955a6ca09

    (Code Snippet – ODataLab - Ex 3.4.1AddItemButton_ClickMethod - VB)

    Visual Basic

    Private Sub AddItemButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    Dim product = TryCast(DirectCast(sender, Button).DataContext, Product) If product IsNot Nothing Then Dim shoppingCart = TryCast(Me.ShoppingCartListbox.DataContext, ObservableCollection(Of ShoppingCart)) Dim item = shoppingCart.SingleOrDefault(Function(i) i.ProductID = product.ProductID) If item Is Nothing Then Dim newShoppingCart = New ShoppingCart() With { .ProductID = product.ProductID, .Product = product, .ItemQty = 1 } shoppingCart.Add(newShoppingCart) Me.AdventureWorks.AddToShoppingCart(newShoppingCart) Else item.ItemQty += 1 Me.AdventureWorks.UpdateObject(item) End If End IfFakePre-6142b814b8b84ab49874ef4b5b71d7f2-362bf53cbb96444e8d48a27ad1e5d437

  2. Locate the DeleteItemButton_Click method and add the following code.

    (Code Snippet – ODataLab - Ex 3.4.2DeleteItemButton_Click Method - CS)

    C#

    private void DeleteItemButton_Click(object sender, RoutedEventArgs e)
    FakePre-a15b93bcabcd4e8285a41a3a1a8d72ff-8effcf1445db45b6aa833e603a774edd var item = ((Button)sender).DataContext as ShoppingCart; if (item != null) { var shoppingCart = this.ShoppingCartListbox.DataContext as ObservableCollection<ShoppingCart>; shoppingCart.Remove(item); this.AdventureWorks.DeleteObject(item); }FakePre-7ab07db1be4d470daf3fac0c99d0af87-37469b91863b45ffa7310f8dc49465e5

    (Code Snippet – ODataLab - Ex 3.4.2DeleteItemButton_Click Method - VB)

    Visual Basic

    Private Sub DeleteItemButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    Dim item = TryCast(DirectCast(sender, Button).DataContext, ShoppingCart) If item IsNot Nothing Then Dim shoppingCart = TryCast(Me.ShoppingCartListbox.DataContext, ObservableCollection(Of ShoppingCart)) shoppingCart.Remove(item) Me.AdventureWorks.DeleteObject(item) End IfFakePre-122abe539d9b4fdb84639a5b185c43b0-60f77cb9bc764666ab81008aeae41b67

    In the preceding code, the selected item is removed from the Shopping cart.

  3. Locate the CheckoutButton_Click method and add the following code to save the shopping cart in the database.

    (Code Snippet – ODataLab - Ex 3.4.3CheckoutButton_Click Method - CS)

    C#

    private void CheckoutButton_Click(object sender, RoutedEventArgs e)
    FakePre-300a2339fa894151ac18a320afb1267d-5dc09fe1d0ed48e28aefc13cb441a46d this.AdventureWorks.BeginSaveChanges(result => { var response = this.AdventureWorks.EndSaveChanges(result); MessageBox.Show("Changes saved successfully!"); }, null);FakePre-1ec70318c45f4d93ac04f3c8fd251588-db26c0feea854104a07ce198ffe7946a

    (Code Snippet – ODataLab - Ex 3.4.3CheckoutButton_Click Method - VB)

    Visual Basic

    Private Sub CheckoutButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    Me.AdventureWorks.BeginSaveChanges(Sub(result) Dim response = Me.AdventureWorks.EndSaveChanges(result) MessageBox.Show("Changes saved successfully!") End Sub, Nothing)FakePre-775950f5b2d8427588451c685f9a0045-48db458ef85b487c8e59a3606222890d

    Note:
    This exercise uses Entity Framework to manage the data access of the application.

  4. You must grant write access to the ShoppingCart resource in the AdventureWorks data service in the WebSite project. To do this, open the AdventureWorks.svc data service code under the WebSite project and add the following code to the InitializeService method:

    (Code Snippet – OData Lab – Ex 3.4.4 - AdventureWorks.svc InitializeService CSharp)

    C#

    public static void InitializeService(DataServiceConfiguration config)
    FakePre-efffc0a8cb5b425284eabd130e3a3c1f-1867a43359a148c1964e7312dd68e7a5FakePre-9f2320f597064d8283fff994809fb29d-3d8a86340db446df8ef5c1f6ff162800 config.SetEntitySetAccessRule("ShoppingCart", EntitySetRights.All);FakePre-503e27988397426d800d33b2531b99f8-22e07976008a4206a722dafd9246832eFakePre-413b1c5047784f37860fa142b6976b53-9f1d153fdc81490a85fa019b70ee3b82

    (Code Snippet – OData Lab – Ex 3.4.4 - AdventureWorks.svc InitializeService VB)

    Visual Basic

    Public Shared Sub InitializeService(ByVal config As DataServiceConfiguration)
    FakePre-0af8750972bb4c1db7e3e9c9f2608a44-cf6aa737d4034acca442302065ea87f2 config.SetEntitySetAccessRule("ShoppingCart", EntitySetRights.All)FakePre-c7797329f0ec47aebf682b17346501b3-000d6231d0344e4fac646ffc29c94439FakePre-ad786bf4567248e0b76154546cdc2320-2c1cf1f730d8487aade303a60eb6455a

  5. Press CTRL+SHIFT+B to build the solution.

Exercise 3 Verification

In this verification, you will explore the Silverlight application; add some products to your shopping cart, and save it to the database.

  1. Set the Website project as the startup project. To do this, right-click the Website project in Solution Explorer, and click Set as StartUp Project.
  2. Set the AdventureWorksShoppingTestPage.html as the startup page, by right-clicking it in Solution Explorer, and then clicking Set As Start Page.

    Figure 25

    Setting the Start Page

  3. Press F5 to run the solution.
  4. In the application, select the Mountain Bike category to display the shopping centers that sell products from this category.

    Figure 26

    The AdventureWorks Shopping application

  5. Click the + button to add some products to the shopping cart. You can also add products from other categories.
  6. Try deleting some products from the shopping cart by clicking in the X button next to the desired product.

    Note:
    The shopping cart is implemented using an Observable Collection instance, therefore when you add or remove products from it, the Datagrid is notified, so it is refreshed to reflect the changes.

  7. When you are ready, click the Checkout button to save the changes to the database. Notice that this is the point where the changes are impacted in the database, when items are added or removed; these operations are kept in-memory.

    Figure 27

    Saving the Shopping Cart

  8. Close Internet Explorer to finish the application.