[Coding] Working with Web API, MongoDB, and BsonDocuments

Posted by Khatharsis on March 3, 2015

After working on the previous tutorial, I decided to get acquainted with the C# driver to perform basic MongoDB queries as the approaches can be quite different between shell and driver. I figured it would be a fairly quick exercise, but I spent an afternoon and then some trying to figure out how to send a BsonDocument as a return type to a Web API method.

Note that I’m not very well-versed with Web API and in retrospect, it’s probably a fairly simple solution, but for all my Google-fu, I couldn’t find the most straightforward answer to my problem. The first being, Web API doesn’t know how to parse a BsonDocument. The second being, passing a raw string as a return type results in JSON parse errors.

For whatever reason, Web API doesn’t know how to handle a BsonDocument, yet it is able to handle custom-crafted C# classes/objects. Go figure. This unfortunate flaw resulted in exceptions and general unhappiness by everyone.

So, I tried to get around this by returning a string. The MongoDB C# driver has a ToJson() method, which seems like a silver bullet, except, like most seemingly silver bullets, it wasn’t. First, ToJson(), when invoked without any settings, will return JSON, but it’s not well-formatted JSON. It doesn’t conform to the standards.

Simple fix. Use JsonWriterSettings to set the OutputMode to Strict:


// MongoDB namespaces used
using MongoDB.Bson;
using MongoDB.Bson.IO;
using MongoDB.Driver;
using MongoDB.Driver.Builders;
using MongoDB.Driver.Linq;

public string GetAllUnicorns() {
	// MongoDB access
	MongoClient client = new MongoClient(conn);
	MongoServer server = client.GetServer();
	MongoDatabase db = server.GetDatabase("learn");
	MongoCollection<BsonDocument> collection = db.GetCollection<BsonDocument>("unicorn");

	// Return all unicorns in the collection in JSON
	MongoCursor<BsonDocument> cursor = collection.FindAll();
	JsonWriterSettings settings = new JsonWriterSettings { OutputMode = JsonOutputMode.Strict };
	string json = cursor.ToJson(settings);
	return json;
}

(Note: snippets from my DAL class)

Great! Except, now JSON is complaining about invalid characters. More specifically, it’s hating the escape character for the double quotes. Okay, let me just strip that out with string.Replace(). No? Okay. Then…I tried out various other things to try and take out that offending backslash, including replacing the double quote with its HTML code, but the JSON parser is stubborn.

The solution, it turns out, is not to return a string, but an HttpResponseMessage:


public HttpResponseMessage Get() {
	HttpResponseMessage response = this.Request.CreateResponse(HttpStatusCode.OK);
	string unicorns = db.GetAllUnicorns();
	response.Content = new StringContent(unicorns, System.Text.Encoding.UTF8, "application/json");

	return response;
}

That finally made the JSON parser happy. And now I can go on my merry way familiarizing myself with basic commands. I hope.

If you are wondering where the unicorns came from, I’m following Karl Seguin’s The Little MongoDB Book.