问题 在尝试解析序列化的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,但我正在处理的方式是简单地执行 string.replace() 在客户端上解析它之前的JSON字符串。我考虑过这样做 ISODate() 但感觉有点太hacky。

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


2585
2018-01-30 20:05


起源

你也有问题 ObjectId(...) 不仅 ISODate。这不是一个有效的json。 - L.B
我删除ObjectId() 在解析它之前从字符串中留下封装的GUID。 - Chad Levy
然后做同样的事情 ISODate,Json.net,ex,可以处理剩下的部分。 - L.B
你可以在解析之前添加一个名为ISODate的全局函数吗? - LameCoder


答案:


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

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

9
2018-01-31 00:07



这正是我想要的。我更喜欢生成的JSON不需要在客户端上进行按摩。谢谢! - Chad Levy
它可以生成'有效'的JSON,但它会产生一些非常糟糕的值。日期变成{输入:{$ date:190012312211}},这是一个典型的应用程序将很难做一些有用的事情。自定义JSON.NET转换器可以修复但仍然。如果JsonOutputMode真的很好。严格可以产生'标准'Json。 - Rick Strahl


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

3
2018-01-30 20:37





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

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

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

2
2017-10-05 14:53





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

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

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

现在 contact 将具有预期值。


1
2018-02-07 14:36





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

object val = BsonTypeMapper.MapToDotNetValue(bsonDocument);
string jsonString = JsonConvert.SerializeObject(val);

1
2017-09-27 12:52





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

0
2017-07-21 00:36



不鼓励代码只回答 - Enamul Hassan