UPDATE: Fixed a few bugs in the downloadable sample including one where it wouldn’t work in Office 365 based CRM Online subscriptions.  Edited some text in the post for clarity.

UPDATE2: Added some text about how to get this working for Windows Authentication.

UPDATE3: I've just blogged about an update to the sample here.  The updates in the code might make following this post a little confusing.  The reason is that due to the final terminology for Windows Store Apps, I needed to refactor the solution/project files and class names.  While I plan on updating this post soon, I wanted to get the changes published.  Hopefully, the naming changes are obvious enough for folks until I update this post. 

Scenario:

“I want to build a Windows 8 Metro style application.  Since my app is going to just perform CRUD operations, I want to use the OData service using json so that I have the least amount of ‘data across the wire’ possible.”

DISCLAIMER: This a pretty hacky approach, but it works and is the only way I know of to do it.  If you like it, use it.  If not, wait until there’s an official sample in the SDK.  You’ve been warned.  I’m just a guy getting creative to solve a problemSmile.

First I will walk you through how to do it.  Then I will explain how it works.  To get started, download and import the following solution into you CRM 2011 organization:

http://sdrv.ms/S3MND1

Next, download the source code of my sample library:

http://sdrv.ms/RYzVzj

I say sample library very loosely.  This is FAR from being a complete, well tested library.  I have good intentions to make it one, but wanted to get a sample of the basic plumbing working for those of you who have asked me how to do it.  This sample should be enough to get you started, but you’ll have to finish out the rest of the functionality.  If anyone wants to take this sample and turn it into an open source project, YOU HAVE MY FULL PERMISSIONSmile.

USING THE SAMPLE

Create a new Metro style app.  I am going to use the Blank App template to keep things simple:

image

Add my sample library to the solution:

image

Don’t forget to right-click References nod of the Crm2011MetroStyleODataApp in Solution Explorer and a reference to the project you just added:

image

image

Find the Devkeydet.CrmMetroODataHelper.csproj file and add it.  Replace the default Grid in MainPage.xaml with the following:

<Grid x:Name="LayoutRoot" Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
    <StackPanel x:Name="MainUIStackPanel" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Collapsed">
        <TextBlock x:Name="myTextBlock" Text="TextBlock" TextAlignment="Center" />
        <Button x:Name="queryButton" Content="Button" />
    </StackPanel>
</Grid>

In MainPage.xaml.cs, paste the following code into the OnNavigatedTo method:

var oDataHelperWebResource = "https://devkeydet.crm.dynamics.com/WebResources/dkdt_/MetroODataHelper.htm";
 
if (!CrmMetroODataHelper.IsLoggedIn)
{
    CrmMetroODataHelper.SignIn(oDataHelperWebResource, LayoutRoot);
    CrmMetroODataHelper.SignInComplete = () => MainUIStackPanel.Visibility = Visibility.Visible;
}

Make sure to replace “https://devkeydet.crm.dynamics.com” with the right url for you.  You will have to add a using Devkeydet statement to the file.  Ok, now it’s time to “Add Service Reference” to the OData service.  Unless you are using Windows Authentication, you can’t point the “Add Service Reference” dialog to the data service url.  Instead, you need to download it and point to it locally, from Visual Studio:

image

image

Save it somewhere and point, then “Add Service Reference” by pointing Visual Studio to the file:

image

Add the following method to MainPage.xaml.cs:

private  async void ExecuteODataQueryAsync()
{
    var ctx =
        new devkeydetContext(new Uri("https://devkeydet.crm.dynamics.com/XRMServices/2011/OrganizationData.svc/"));
 
    // Use the generated DataServiceContext to compose the query using LINQ, 
    // but get the string of the query via ToString().
    // We still get to use the query composition capabilities of LINQ!
    var query = from a in ctx.AccountSet
                where a.Name.StartsWith("A")
                select new Account
                {
                    Name = a.Name
                };
 
    var accounts = await CrmMetroODataHelper.RetrieveMultipleRecordsAsync<Account>(query.ToString());
 
    myTextBlock.Text = accounts.First().Name;
}

Again, remember to replace “https://devkeydet.crm.dynamics.com” with the right url for you.  You will have to add a using statement based on the Namespace you gave the generated code and devkeydetContext will need to be replaced with your generated context name.  Now, wire up an event handler for the button (ex: double click the button on the design surface) and call the method:

ExecuteODataQueryAsync();

If your app is using Windows Authentication, then you need to double-click on the Package.appxmanifest and make sure you have the following Capabilities checked:

image

Go ahead and run the app.  You will be prompted for your credentials if necessary:

image

Sign in with your credentials, click the button, and the TextBlock should have the value of the Name property of the first result:

image

There you go!  You just issued an OData query from a C# Metro style app!

HOW THE SAMPLE WORKS

The sample wraps the WebView control.  The WebView control tries to load an html web resource from the CRM server (that’s what’s in the devkeydetMetroODataHelper_1_0.zip solution).  If you haven’t logged in, then the WebView is set to be visible and it will just present you with the web based login UI.  Once logged in, the WebView visibility is collapsed and the C# wrapper basically proxies OData calls through WebView via the web resource using a modified version of the SDK.REST.js file from the CRM 2011 SDK.  The major modification is that the default SDK.REST.js sample will turn the resulting json string into an JavaScript object.  Instead, I just pass the json string back to the C# wrapper and use JSON.NET to turn it into C# objects.

As I mentioned earlier, this is FAR from being a complete and reusable library.  I have good intentions to make it one, but wanted to get a sample of the basic plumbing working for those of you who have asked me how to do it.  This sample should be enough to get you started, but you’ll have to finish out the rest of the functionality.  I only implemented executing a query that returns multiple results.  Furthermore, I didn’t handle continuation tokens.  If anyone wants to take this sample and turn it into an open source project, YOU HAVE MY FULL PERMISSIONSmile.

@devkeydet