Handling MongoDB's ISODate() when attempting to parse a serialized JSON string

I'm using MongoDB via the official C# driver with an ASP.NET MVC web site.

I have the following C# model:

public class Contact
{
    public ObjectId Id { get; set; }
    public string Name { get; set; }
    public DateTime DateAdded { get; set; }
}

Which, when pulled from MongoDB and serialized into a JSON string via MVC looks like:

{
    "_id"  : ObjectId("52eaad4839b60812fca4bf28"),
    "Name": "Joe Blow",
    "DateAdded" : ISODate("2014-01-30T19:51:35.977Z")
}

When I attempt to convert this from a JSON string to a Javascript object on the browser via JSON.parse(), I get the following error:

Uncaught SyntaxError: Unexpected token I

This is because ISODate(...) is not valid JSON

ObjectId() is also not valid JSON, but the way I'm handling that is to simply perform a string.replace() on the JSON string prior to parsing it on the client. I considered doing the same for ISODate() but it feels a little too hacky.

Is there something I can do without resorting to regular expressions on the client side? Perhaps something from the MongoDB driver?

Asked By: Chad Levy
||

Answer #1:

I think you need to tweak your JSON serializer a bit more. Try this:

var jsonWriterSettings = new JsonWriterSettings { OutputMode = JsonOutputMode.Strict };
Console.WriteLine(document.ToJson(jsonWriterSettings));
Answered By: Chad Levy

Answer #2:

You SHOULD use JsonConvert to properly convert the Date to Json. the accepted answer produces a date object like: { $date: 190012312211 } as @Rick Strahl mentioned. This should work:

object val = BsonTypeMapper.MapToDotNetValue(bsonDocument);
string jsonString = JsonConvert.SerializeObject(val);
Answered By: Neil Lunn

Answer #3:

If the JSON data is safe for eval (since its coming from your server it probably is) then you can do like so. It's not particularly pretty, but it gets the job done.

http://jsfiddle.net/CVLhx/

var str = '{"_id"  : ObjectId("52eaad4839b60812fca4bf28"),"Name": "Joe Blow","DateAdded" : ISODate("2014-01-30T19:51:35.977Z")}';

function ObjectId(id) { return id;}
function ISODate(d) {return d;}

var obj = eval('(' + str + ')');
console.log(obj);
Answered By: Louie Almeda

Answer #4:

as @Louie Almeda suggests, i think the best approach is with the BsonTypeMapper.MapToDotNetValue. BsonTypeMapperOptions can be customized too.

Here's what i'm using to convert a list on BsonDocument to a json string using LINQ and newtonsoft serializer :

var jsonString = JsonConvert.SerializeObject(bsonDocuments.ConvertAll(d => BsonTypeMapper.MapToDotNetValue(d)), Formatting.Indented)
Answered By: LameCoder

Answer #5:

I realize that I am very late to this party but I'll post an answer anyway in case somebody else comes along looking for a solution (as I did).

The trick is to let the Mongo db driver do the deserialization:

var collection = database.GetCollection<Contact>("collection name");
var contact = collection.Find(Query.EQ("Name", "Joe Blow"));

Now contact will have the expected values.

Answered By: Thomas-Louis Simard

Answer #6:

 var IDict = v as IDictionary<string, object>;
                        var dict = IDict.ToDictionary(x => x.Key, x => x.Value);
                        var dateVal = dict["$date"];
                        var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
                        var dateTimeVal = epoch.AddMilliseconds(Convert.ToDouble(dateVal));
Answered By: pberggreen
The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .



# More Articles