I would like to have ASP.NET MVC return a document stored in MongoDB as JSON, but have no need for it to be serialized to a .NET type first. However, BSONDocument.ToJSON() returns JSON that looks like this:
{_id:ObjectId("someid")}
The browser's JSON parser does not like "ObjectId(nnn)" and so the call fails with a parser error. I am able to get parse-able JSON using a Regex hack:
public ActionResult GetFormDefinitionsJSON()
{
var client = new MongoDB.Driver.MongoClient(ConfigurationManager.ConnectionStrings["mongodb"].ConnectionString);
var db = client.GetServer().GetDatabase("formthing");
var result = db.GetCollection("formdefinitions").FindAll().ToArray();
var sb = new StringBuilder();
sb.Append("[");
var regex = new Regex(@"(ObjectId\()(.*)(\))");
var all = result.Select(x => regex.Replace(x.ToJson(), "$2"));
sb.Append(string.Join(",", all));
sb.Append("]");
return Content(sb.ToString(), "application/json");
}
This returns parse-able JSON:
{_id:"someid"}
But it smells. Is there any way without regex and string building hackery to get the official MongoDB driver to return JSON that can be parsed by the browser? Alternatively, am I missing something on the browser side that would allow {_id:ObjectId("someid")} to be parsed as valid?
You have two options that I can think of.
The first one is to use the JavaScript JsonOutputMode
mode. This results in the ID serializing to "_id" : { "$oid" : "51cc69b31ad71706e4c9c14c" }
- not quite ideal, but at least it's valid Javascript Json.
result.ToJson(new JsonWriterSettings { OutputMode = JsonOutputMode.JavaScript })
The other option is to serialize your results into an object and use the [BsonRepresentation(BsonType.String)]
attribute. This results in much nicer Json: "_id" : "51cc6a361ad7172f60143d97"
; however, it requires you to define a class to serialize it in to (this can affect performance)
class Example
{
[BsonId]
[BsonRepresentation(BsonType.String)]
public ObjectId ID { get; set; }
public string EmailAddress { get; set; }
}
// Elsewhere in Code - nb you need to use the GetCollection<T> method so
// that your result gets serialized
var result = database.GetCollection<Example>("users").FindAll().ToArray();
var json = result.ToJson();
Some more details on the differences between JsonOuputModes (Strict, Javascrpt and Mongo):
http://docs.mongodb.org/manual/reference/mongodb-extended-json/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With