在尝试解析序列化的JSON字符串时处理MongoDB的ISODate()

我通过官方C#驱动程序使用MongoDB和ASP.NET MVC网站。

我有以下C#模型:

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

从MongoDB中提取并通过MVC序列化为JSON字符串时,如下所示:

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

当我尝试通过JSON.parse()将其从JSON字符串转换为浏览器上的Javascript对象时,我收到以下错误:

Uncaught SyntaxError: Unexpected token I

这是因为ISODate(...)不是有效的JSON

ObjectId()也不是有效的JSON,但我正在处理的方法是在JSON字符串上执行string.replace()之前在客户端上解析它。 我考虑过为ISODate()做同样的ISODate()但感觉有点过于hacky。

如果不在客户端使用正则表达式,我能做些什么吗? 也许来自MongoDB驱动程序的东西?

我想你需要更多地调整你的JSON序列化器。 试试这个:

 var jsonWriterSettings = new JsonWriterSettings { OutputMode = JsonOutputMode.Strict }; Console.WriteLine(document.ToJson(jsonWriterSettings)); 

如果JSON数据对于eval是安全的(因为它可能来自你的服务器),那么你可以这样做。 这不是特别漂亮,但它完成了工作。

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); 

正如@Louie Almeda建议的那样,我认为最好的方法是使用BsonTypeMapper.MapToDotNetValue。 BsonTypeMapperOptions也可以自定义。

这是我使用LINQ和newtonsoft序列化器将BsonDocument上的列表转换为json字符串的方法:

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

我意识到我参加这个派对的时间已经很晚了但是我会发布一个答案,以防其他人出现寻找解决方案(正如我所做的那样)。

诀窍是让Mongo db驱动程序进行反序列化:

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

现在contact将具有预期值。

您应该使用JsonConvert将Date正确转换为Json。 接受的答案产生了一个日期对象,如: { $date: 190012312211 }正如@Rick Strahl所提到的那样。 这应该工作:

 object val = BsonTypeMapper.MapToDotNetValue(bsonDocument); string jsonString = JsonConvert.SerializeObject(val); 
  var IDict = v as IDictionary; 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));