Can't serialize BsonDocument to Json from MVC3 using official C# driver Can't serialize BsonDocument to Json from MVC3 using official C# driver mongodb mongodb

Can't serialize BsonDocument to Json from MVC3 using official C# driver


I don't see any reason why you would need to create an object model for this, unless MVC3 is imposing that requirement on you. Using BsonDocument and serializing straight to a JSON string should be fine. It's hard to wade through most of your post, but zeroing in on the result of calling MapReduce, the GetResults() method returns a value of type IEnumerable<BsonDocument>, which you should be able to easily convert to JSON. Here's a simple test:

IEnumerable<BsonDocument> results = new BsonDocument[] {    new BsonDocument("x", 1),    new BsonDocument("x", 2)};var json = results.ToJson();

When I run this code the json variable end up with the following content:

[{ "x" : 1 }, { "x" : 2 }]

In particular, I don't get the exception you mentioned. Can you make sure you are using a new enough version of the C# driver, and if you still get the exception post back the full stack trace?

Part of the problem might be coming from mixing and matching BsonDocument with a JSON serializer that is not part of the C# driver. Third party JSON serializers (like the Json method you are using that returns a JsonResult) typically impose their own constraints on what they can and can't serialize. So the problems you are encountering would appear to be external to the MongoDB C# driver.

Sorry, I really don't know enough about MVC3 and how it expects to converts results back to JSON to say much about that.


So, I've written a one-way plugin for Json.Net that will allow me to serialize BsonDocuments using the toJson() method on the document itself. It's not ideal because I now have two different serializer stacks;

public class BsonDocumentConverterPlugin : Newtonsoft.Json,JsonConverter{    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)    {        BsonDocument bsonDoc = (BsonDocument)value;        writer.WriteRaw(bsonDoc.ToJson());    }    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)    {        throw new NotImplementedException("Serialisation back to Bson not supported in this converter");    }    public override bool CanConvert(Type objectType)    {        return (objectType == typeof(BsonDocument));    }}

and in my JsonResult override;

        var serializedObject = JsonConvert.SerializeObject(Data, Formatting.None,                 new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore,                                             Converters = new List<JsonConverter>() { new BsonDocumentConverterPlugin() }                });

Unfortunately, this doesn't appear to work for my MapReduce resultset which has multiple results as it doesn't serialise them as an array and misses the commas out resulting in the invalid json, no matter which serialization method I use. BsonDocument.ToJson() also writes invalid json for dates. Under strict it writes ISODate() and under JavaScript/TenGen it writes newDate(). Both of these cause my browser to barf.

So in the end, I've had to resort to building an object graph after all;

    public class MrResultsetCashflow    {        [MongoDB.Bson.Serialization.Attributes.BsonId]        public DateTime date { get; set; }        public FinancialItem value;    }

and I go through the original MVC/json.net serialization stack;

        var f = mr.GetResultsAs<MrResultsetCashflow>();        return Json(f, JsonRequestBehavior.AllowGet);