Using OData protocol V3 with MongOData OData provider

In a recent post I showed how MongOData (it’s a MongoDB OData provider that I wrote and maintain) exposes BsonArray MongoDB properties. Support for arrays of primitive and complex types has been added to OData protocol in its latest version 3, but many clients and code generation tools haven’t been enhanced with this feature, so they will fail accessing a MongoDB collection where some items are exposed as arrays.

Moreover, due to the nature of document databases, array is a natural way of exposing collections of items, versus one-to-many relationship used in relational database. So the chances are pretty high that an arbitrary MongoDB repository will contain documents that will break old generation client tools.

Let me show you this on a simple example. I’ve been working on a set of MongOData samples that would illustrate how to set up and use the provider, and once I tried to generate a WCF Data Services client proxy using Visual Studio 2010, it showed me the following error message:

DataServiceVersionError

The offending part was the Product class definition that contained an array of Suppliers:

public class Supplier
{
    public string Name { get; set; }
    public Address[] Addresses { get; set; }
}

So what can you do to overcome such limitation? It’s really silly not to be able to retrieve data structure that both service can expose and your code can consume when all that stops you is a man in the middle: a proxy generation tool.

My answer to this is simple: bypass proxy generation. OData protocol follows REST principles, and proxy generation is so SOAP. Just use C# dynamics so the service metadata will be evaluated at runtime.

One simple approach to achieve this is to use Simple.Data OData adapter. Here’s the code that retrieves the content of MongoDB collection (containing arrays) using Simple.Data:

Console.WriteLine("Connecting to MongoDB sample OData service...");
dynamic context = Database.Opener.Open("http://localhost:50336/MongoDataService.svc/");

Console.WriteLine("Retrieving categories...");
Console.WriteLine();
foreach (var category in context.Categories.All().ToList())
{
    Console.WriteLine("Category: ID=[{0}], Name=[{1}]",
        category.ID,
        category.Name);
}
Console.WriteLine();

Console.WriteLine("Retrieving products...");
Console.WriteLine();
foreach (var product in context.Products.All().ToList())
{
    Console.WriteLine("Product: ID=[{0}], Name=[{1}], Category=[{2}], Quantity=[{3} {4}], " +
                      "ReleaseDate=[{5}], DiscontinueDate=[{6}], Suppier=[{7}]",
        product.ID,
        product.Name,
        product.Category.Name,
        product.Quantity.Value,
        product.Quantity.Units,
        product.ReleaseDate,
        product.DiscontinueDate,
        product.Supplier == null ? null : product.Supplier.Name);
}

I created MongOData.Samples solution with the following projects:

  • CreateSampleData – creates a sample MongoDB database (default connection string is set to mongodb://localhost/mongodatasamples, you can of course change it), during creation is asks if you want to enable OData protocol V3 support;
  • SampleService – WCF Data Service provider that uses MongOData to connect to a MongoDB instance;
  • SampleWcfDataServiceClient – OData client that uses proxy classes generated by Visual Studio, so it can not consume services that use OData V3 features such as arrays;
  • SampleDynamicClient – proxy-less client that uses Simple.Data OData adapter and support OData V3 features.

You can download sample solution here.

Advertisements

5 thoughts on “Using OData protocol V3 with MongOData OData provider

  1. None of your source code links appear to be valid. I’m really struggling to get the MongOData provider to work with Lightswitch and Excel. They don’t appear to support nested documents (or the methods generated by the driver to support them). I’m really keen to see how we can implement via the Simple Data adapter.

    • Hi Gavin,
      Sorry for broken links – this blog post was auto-imported from my old blog, and apparently links didn’t survive the conversion. Let me understand what you’re trying to achieve. Do you want to expose your data as OData feed from a MongoDB database, or you want to consume OData feed using Simple.Data OData adapter (or Simple.OData.Client which has more features)?

      • Hi, and thanks for getting back to me so promptly. I’m trying to get Excel, or Silverlight to consume MongoDB data. I’ve produced a web service, as per your code to deliver oData service, which works fine for a single level document, but… and you know where this is going… any usable document with nested data isn’t supported. This may well be because, even in latest versions, these Ms products don’t support V3 & v4 of oData properly or at all, but what I’m trying to do is find a way round this limitation. Would Simple.oData provide an option to do this, or is there anyway that you can suggest to get MongOData to meet these client application limitations?

  2. Perhaps you can have a look at MongOData tests – they have plenty of examples with nesting (it’s on GitHub). Otherwise, you can open an issue at at MongOData GitHub repo with description of what works and what not and link to the sample files. I can take a look at it.

    Simple.OData.Client is just a client (http://www.odata.org/blog/advanced-odata-tutorial-with-simple-odata-client/). It supports both OData V3 and V4 but has nothing to do with the exposing data as OData feed. So these are two different things.

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