Sunday afternoon ..
Grilled turkey burgers for lunch + wife busy with dissertation = Full & ready to crank out some solid code for a few hours. I rub my hands and sit down to knock off a pending project work. At hand, is a Windows 8 Release Preview Metro app that we are building for a client. Traditional technician-out-with-a-tablet setup; so offline access & later data sync with server DB is called for. The immediate answer is OData, as a service on top of backend Database .. seamlessly & asynchronously read/write data through plain HTTP. I have done OData CRUD numerous times in Windows Phone, web or Silverlight .. this should be a piece of cake!
Yeah, right .. what ensued was a few hours of frustration, trying to stitch together the moving pieces & beta software hurdles to overcome. So, here’s my attempt to save someone a few hours .. don’t you love writing blog posts which will be obsolete in a few weeks? 🙂 Here’s the tale:
- First, the data store. Simple relational data. SQL Azure DB with appropriate Tables. Done.
- Next, expose the data through an OData service layer. SQL Azure Labs had this one click approach to setting up an OData service on top of existing DBs; not sure when that is coming back. So, custom service it is. Two step process to produce an OData service: ADO.NET Entity Data Model (EDM) pointed to DB Tables + WCF Data Service exposing the generated entities. If you need to do full CRUD, make sure you are configuring each entity with the right permissions.
- Host the service in IIS, test & host in Azure. Done.
- Next, integrate in Windows 8 RP Metro app .. should have been simple if I had known what was supported. By the way, if you started writing your Metro app in Consumer Preview in XAML/C#, you’ll find a sleepless night with breaking changes in Release Preview. Expected, but awkward. Just restart fresh project & port over artifacts.
- Turns out, I had gone HERE to get Windows 8 RP. Right next to the RP ISO is the link to download the Dev tools, which happen to be VS 2012 Express for Windows 8. Point is, know what you are running.
- Next, grab OData service URL & hope against hope that Add Service Reference would work .. well, it didn’t. Turns out, not supported in VS 2012 Express.
- No problemo .. been there. So, immediately revert back to the DataSvcUtil.exe tool for Proxy generation. Yup works just fine in .NET 4.5. Check out THIS post if you need the steps.
- Grab the generated proxy file & drop in VS project. Voila, you have references to your OData entities in code. One problem — can’t easily work with them!
- The issue is, Windows 8 Metro apps written on top on WinRT would not allow you to add references to two super-useful class libraries — System.Data & System.Data.Services.Client. These two are the key to working easily with an OData service. Without them, you’ll be left hand-coding the HTTP requests .. Yuck!
- Has no one figured out a way? Well, sure .. and it is Phani Raju from MSFT. The very person whose bits we’re seeing in present VS 2012 RC. Check out his POST explaining how to consume the Netflix OData feed.
- Upon download of the sample code, you should see the following DLL references in the project:
- So, in addition to our generated proxy, could we just grab these DLLs & call it a day? Well, sure it compiles and we can use DataServiceContext/DataServiceCollection; but you get runtime exceptions around Type initializers. Closer reading of Phani’s post & comments reveal that the bits have changed some & not compatible with VS 2012 RC any more. Updated libraries have been shipped; but as a part of VS 2012 RC Ultimate!
- Aha, so that’s a problem .. Adding a Service Reference is not yet supported in the VS 2012 RC Express for Windows 8 Metro apps only; we need to get the Ultimate edition from HERE.
- One caveat – Do not install VS Ultimate on top of the Windows 8 Metro Express version; references still seemed broken. So, uninstall what you have & get the fresh full copy of VS 2012 RC Ultimate.
- Now, you should be set. And guess what, no more manual proxy generation or dropping DLLs. Simply grab the URL of your WCF/OData service and do Add Service Reference. Should work.
- And when you do successfully add reference, take a look at your project references .. yep, it has added back the same 3 DLLs we saw above; only with updated bits. Voila!
- And now, you can add references to System.Data & System.Data.Services.Client in your code. These seem to be non-accessible by default; upon service addition, the newly dropped DLLs open up these namespaces.
- That’s it: Now you can create a DataServiceCollection to pull down your OData entities and do full CRUD operations, if allowed by the data source. See this POST if you need pointers on how to do CRUD against OData.