Updating OData data source from WP7 .. Part 1

Posted: July 24, 2011 in Azure Goodness, Windows Phone 7
Tags: , , ,

This will be a longish post .. you have been warned :)

I think OData is rather cool .. head over (here) to learn more, if you haven’t already. There is nothing proprietary  about it; just culmination of existing technologies of HTTP, AtomPub and Json to provide a platform independent way of sharing information. As I heard someone say “..think of it as RSS for real updateable data..” and in this new age of www as a collection of connected web services rather than collection of web pages, I think OData can play an important role. Why the restrictions against opening up our data to interoperability if we can put adequate security on it?

Now, I wanted to talk about OData from a Windows Phone standpoint (specially WP7.5 or Mango); but also something that applies equally & is just as easily doable on other mobile OS platforms. Most well-designed mobile solutions these days also have a web interface that allows for easier data entry than on a phone form factor; yet data has to stay in sync whenever the user switches between platforms. A centralized data repository with OData feeds seems perfect for a case like this .. so, that’s what we shall talk about in this post.

After looking around a little bit on OData & WP7, I found a lot of examples on how to set up an OData source & consume the feeds from a Windows Phone app. This is obviously the first step & rather important as we shall see; but I also wanted to see if I could set up CRUD operations from WP7 back to the OData source. In the meantime, check out these few posts on how to consume OData in the first place:

  • Surely, one of the best ways to play with OData in real world is the Netflix catalog. Netflix worked with MSFT to expose their entire data set through an OData service (here) and now it becomes easy for various applications to consume the vast information in their catalog. This series of posts (here) covers how to build a Windows Phone client to browse through the Netflix catalog.
  • Michael Crump did this brilliant series on how to set up an OData source & consume it in Silverlight/Windows Phone. You may find it (here).
  • Post (here) from your’s truly on how to consume OData feeds from SQL Azure in a Windows Phone app.

Now all this is cool; but what if you wanted to update the OData source from your Windows Phone app? Isn’t that the promise of OData? Sure, we can do CRUD in Windows Phone 7.0; it just gets much easier in Mango. And the beauty of it is that it can be done completely without adding a service reference (proxy) to the OData service; simply HTTP Post with the correct request at the right URL. And this works the same way in iOS, Android or any darn platform .. that is where lies the nicety of OData.

For our data repository, lemme again chose SQL Azure, which gives us a nice way to expose our data globally through a simple OData feed. Please see my previous post (here) on how to set up a simple web application to reach out to create/manipulate data in SQL Azure & have it consumed in a Windows Phone app. Now, we really want the Windows Phone version to be able to update data records back in Azure & have it picked up seamlessly in the web application or any other consumer .. wouldn’t that be nice!

So, we start with a simple table called “Team” which is hosted in SQL Azure & has the data schema as below:

SQL Azure Team Table

The data in the table is then exposed out as an OData service with these steps:
  • Heading over to https://www.sqlazurelabs.com/ and logging in to the OData service with admin credentials.
  • Then, we select the DB & Table and check the OData checkbox.
  • For authentication, we select Anonymous Access so that anybody may access the data without security sign-ons. In real world, this is obviously not good practice. In essence however, Anonymous Access really uses the “dbo” or your admin credentials for SQL Azure operations. So, it should not be too difficult to create users for SQL Azure access & giving them appropriate access rights. This way, the OData service will require submission of security tokens (through ACS or some other federated authentication source) for data access/updates. This post (here) describes the intricacies of the Azure OData service wonderfully. Make sure you copy the OData URL as exposed by your SQL Azure instance.

Next, we talk about 3 ways in performing updates to the underlying SQL Azure database through the OData service. First, through our own hosted service in Azure. Here are the steps:
  1. Make sure you have the Azure VS SDK (get is from here). This ensures that we can create projects with the Azure wrapper so that our service may be hosted easily in Azure.
  2. File — New Project — Cloud — Windows Azure Project. This creates the Azure wrapper project. Let’s add an ASP.NET Web Application project to be hosted as Web Role.
  3. In the ASP.NET project, Add a new item of type ADO.NET Data Entity. This is essentially the ORM mapper that reflects on DB schema and gives us .NET object to play with. In the setup wizard, we make it use an Existing DB & point to the OData Service URL as exposed by our SQL Azure table. You will be required to enter your SQL Azure Admin DB credentials or some other user access details. This should build the proxies out of the OData metadata, and thus expose the service offerings to our project. For our “Team” table in SQL Azure exposed through OData, the data model looks like this:
  4. ADO.NET Data Entity

     

     

     

     

     

     

     

     

     

     

     

  5. Next, we add a WCF Data Service to the project which should expose out the data provided by the ADO.NET data service. The configuration of the SVC.cs file should look something like this:
  6. 
    using System;
    using System.Collections.Generic;
    using System.Data.Services;
    using System.Data.Services.Common;
    using System.Linq;
    using System.ServiceModel.Web;
    using System.Web;
    
    namespace WebRole1
    {
        public class DemoService : DataService
        {
            // This method is called only once to initialize service-wide policies.
            public static void InitializeService(DataServiceConfiguration config)
            {
                config.SetEntitySetAccessRule("Teams", EntitySetRights.All);            
                config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
            }
        }
    }
    
    

  7. Notice how we ask for building a collection of data objects of the same entity type as exposed by our ADO.NET data model. Also, we allow this service to have access rights of “All ” so that we may perform CRUD against the SQL Azure table at will.
  8. If everything goes well, we should be able to right-click on the .SVC file & do a “View in Browser“. This should get us to the same OData view as in Azure; you should be able to drill in & see all your data through OData filtering on browser URL.
  9. Local WCF Service exposing OData


     

  10. So, by now we have our own service ready & pointed to the SQL Azure OData service with user credentials configured as needed. Now, this service is ready for primetime hosting in Azure.
  11. We right click on the solution & choose “Publish” and create the packages locally in our bin directory. This makes two files — a .cspkg application wrapper & a .cscfg configuration file.
  12. We simply create a new Hosted Service in Azure and push out these files & swap their IP to be Production. The end state looks something like this:

WCF Service in Azure

That’s it! We now have our own configured WCF Service hosted in Azure. We can try hitting the Production SVC URL to make sure we have access to the same OData stream.

Now, let’s switch focus to our Windows Phone app. We can obviously read data out of the Azure OData feed pretty easily, as evident (here). What we want to be trying to do is to add records into the SQL Azure table from the Windows Phone app. Accordingly, we add a little UI for allowing data entry; end goal is something like this:

Team in WP7

Added Team Member through WP7

The way we go about doing this is by adding a Reference to our own WCF Service hosted in Azure, as below. Please note, that this will work only in Windows Phone 7.1 Mango tooling:

Add WCF Service Ref.

With the service reference under our belt, we now have a direct context of the OData service in Azure. Accordingly, we can have access to “Team ” collection objects in code & be able to manipulate them at will. In our case, we already have Sam & Jeff in the SQL Azure table; we want the phone app to add a new member Mike. Here’s some code:


using Demo;
using System.Data.Services.Client;

namespace SQLAzureOData_Demo
{
    using DemoService;

    public partial class MainPage : PhoneApplicationPage
    {
       private static DemoEntities wcfContext = null;

       private void InsertDataThruService()
        {
            wcfContext = new DemoEntities(new Uri("http://YourAzureServiceNDS.cloudapp.net/DemoService.svc/"));

            var TeamMember = Team.CreateTeam(3);
            TeamMember.Name = "Mike";
            TeamMember.TwitterHandle = "@michaelcollier";

            var collection = new DataServiceCollection(wcfContext);
            collection.Add(TeamMember);
            wcfContext.BeginSaveChanges(new AsyncCallback(SaveChangesCB), null);
        }

        private void SaveChangesCB(IAsyncResult asynchronousResult)
        {
            // Warning: You are on a different thread!
            // Success or Error Handling.
            Dispatcher.BeginInvoke(() =>
                {
                    MessageBox.Show("All done!");
                    LoadTeam();
                });
        }
     }
}

Just a few points to mention. On hitting the “+” App icon, I have a little UI pop-up that accepts the new Team members Name & TwitterHandle. The code sample above hard-codes the user; but you get the point that the UI needs to fire the “InsertDataThruService” method. Once we have the “WCFContext”, you can see how easy it gets to manipulate the data through any CRUD operations. Another important point to keep in mind is that the “BeginSaveChanges” call is asynchronous, this being Silverlight. So, the “SaveChangesCB” callback delegate does not fire on the same UI thread. This is important to keep in mind if you start wondering why the message pop-up or the refresh of the Team member list in our case, does not fire.

That’s it, few steps; but now we have a fully functional data repository that exposes OData feeds and can be read/updated from multiple platforms. This Service Reference way is just one way to do CRUD on an OData service though. In the next post, we talk about how to do this natively.

Hope this was helpful.

Adios!

About these ads
Comments
  1. merasheen says:

    I have a very similar setup, but when i try to update the odata service, i get a simple “NotFound” response. I’m not adding but simply changing a record.
    Any ideas

    • Samidip says:

      Merasheen,

      Sorry to be late in replying. Little more context will help. How did you set up your OData service? Is the entity in question set up to allow edits? How are you constructing your update logic? Please feel free to email if you want to take this off-line.

      Thanks!

  2. Michael says:

    great post thank you very much!
    one question though, i’ve created a “windows phone cloud application” project from the template of windows phone toolkit for windows azure. there, in the web project i can see a directory called services which have all the DataService classes.
    i dont see any .svc files, only .cs but nevertheless the phone can communicate with the asp.net mvc3 server application. is it using a different method than the one you described ? the DataService class is defined as:
    public class SqlAzureSampleODataService : DataService and it is consumed on the WP client side, but no svc file…

    • Samidip says:

      Michael,

      Yes .. you are right. No WCF endpoint as such. The Web project created by the template is an MVC app, with Controller acting as endpoints through routing. Take a look at the App.xaml resources in the WP app for endpoints and then the PushNotificationsController.cs in the web app.

      Hope this helps! Glad to see you trying things out & poking inside the workings of the toolkit.

      Thanks!

      • miked says:

        thanks a lot for the direction !
        Do you know where i can i read about this method or maybe a tutorial that is using the same pattern ? because most of the stuff i read are about using WCF and consuming the services.

        Thanks again for the answer.

  3. Samidip says:

    miked,

    It depends on what you are trying to accomplish through your service/MVC action. Try this: http://stackoverflow.com/questions/3499514/wcf-rest-service-or-asp-net-mvc-controllers-actions. You could also read up on MVC tutorials that’ll show how to have MVC ActionResults serve up JSon/XML. The important distinction is that it is not a standalone web service like WCF.

    Thanks!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s