Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can the C# MongoClient be used to return valid JSON without first serializing to a .NET type?

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?

like image 998
Daniel Avatar asked Feb 16 '23 04:02

Daniel


1 Answers

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/

like image 54
Shaun McCarthy Avatar answered Feb 18 '23 22:02

Shaun McCarthy