在控制器中将弱类型的 BsonDocument 序列化为 JSON
Serializing weak typed BsonDocument to JSON in controller
我的 MongoDB 驱动程序有问题。我正在编写一个由 JavaScript 前端使用的 .Net Core web api。有一个Parent
和Child
class。在 child class 中,我想实现一个弱类型字段,我可以在其中输入任何 JSON
值,只是一个常规的 key/value 存储。这是我的设置:
public class Child
{
public int Id { get; set; }
public string Type { get; set; }
public BsonDocument Properties { get; set; }
}
public class Parent
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public List<Child> Children { get; set; }
}
在数据库中,parent 元素可能如下所示:
{
"_id" : 1,
"Children" : [
{
"_id" : 1,
"Type" : "TEXT",
"Properties" : {
"Width" : 100,
"Height" : 100,
"Color" : "red"
}
}]
}
从数据库中读取数据就是这样工作的。 MongoDB 正在反序列化数据,一切正常。我遇到的问题是在控制器级别。这是相当简单的控制器代码:
[HttpGet]
public ActionResult<List<Parent>> Get()
{
// _parentRepository.Get() is returning a List<Parent> read from the DB
return _parentRepository.Get();
}
但是当我向 API 发送请求时,我得到的结果是:
{
"id" : 1,
"children" : [
{
"id" : 1,
"type" : "TEXT",
"properties" : [
{
"name": "Width",
"value": 100
},
{
"name": "Height",
"value": 100
},
{
"name": "Color",
"value": "red"
}
]
}]
}
正如您所见,BsonDocument
像字典一样被序列化,它是 key/value 对的列表。我宁愿在那里有一个平面 JSON,所以表示与数据库中的完全一样。
我尝试使用 JsonResult
并显式转换为 Controller.Json()
,但结果是一样的。
注意:我正在使用 .NET Core 2.2
!我知道 3.0 引入了一些与 JSON 相关的更改,但还不能更新项目。
谢谢!
这就是 Newtonsoft.Json
将 BsonDocument
类型序列化为 string
的方式。您可以轻松解决引入自己的序列化程序和 运行 BsonDocument.ToJson()
方法的问题:
public class BsonToJsonConverter : JsonConverter<BsonDocument>
{
public override BsonDocument ReadJson(JsonReader reader, Type objectType, BsonDocument existingValue, bool hasExistingValue, JsonSerializer serializer)
{
JToken token = JToken.Load(reader);
return BsonDocument.Parse(token.ToString());
}
public override void WriteJson(JsonWriter writer, BsonDocument value, JsonSerializer serializer)
{
writer.WriteRawValue(value.ToJson());
}
}
装饰你的类型:
public class Child
{
public int Id { get; set; }
public string Type { get; set; }
[JsonConverter(typeof(BsonToJsonConverter))]
public BsonDocument Properties { get; set; }
}
我的 MongoDB 驱动程序有问题。我正在编写一个由 JavaScript 前端使用的 .Net Core web api。有一个Parent
和Child
class。在 child class 中,我想实现一个弱类型字段,我可以在其中输入任何 JSON
值,只是一个常规的 key/value 存储。这是我的设置:
public class Child
{
public int Id { get; set; }
public string Type { get; set; }
public BsonDocument Properties { get; set; }
}
public class Parent
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public List<Child> Children { get; set; }
}
在数据库中,parent 元素可能如下所示:
{
"_id" : 1,
"Children" : [
{
"_id" : 1,
"Type" : "TEXT",
"Properties" : {
"Width" : 100,
"Height" : 100,
"Color" : "red"
}
}]
}
从数据库中读取数据就是这样工作的。 MongoDB 正在反序列化数据,一切正常。我遇到的问题是在控制器级别。这是相当简单的控制器代码:
[HttpGet]
public ActionResult<List<Parent>> Get()
{
// _parentRepository.Get() is returning a List<Parent> read from the DB
return _parentRepository.Get();
}
但是当我向 API 发送请求时,我得到的结果是:
{
"id" : 1,
"children" : [
{
"id" : 1,
"type" : "TEXT",
"properties" : [
{
"name": "Width",
"value": 100
},
{
"name": "Height",
"value": 100
},
{
"name": "Color",
"value": "red"
}
]
}]
}
正如您所见,BsonDocument
像字典一样被序列化,它是 key/value 对的列表。我宁愿在那里有一个平面 JSON,所以表示与数据库中的完全一样。
我尝试使用 JsonResult
并显式转换为 Controller.Json()
,但结果是一样的。
注意:我正在使用 .NET Core 2.2
!我知道 3.0 引入了一些与 JSON 相关的更改,但还不能更新项目。
谢谢!
这就是 Newtonsoft.Json
将 BsonDocument
类型序列化为 string
的方式。您可以轻松解决引入自己的序列化程序和 运行 BsonDocument.ToJson()
方法的问题:
public class BsonToJsonConverter : JsonConverter<BsonDocument>
{
public override BsonDocument ReadJson(JsonReader reader, Type objectType, BsonDocument existingValue, bool hasExistingValue, JsonSerializer serializer)
{
JToken token = JToken.Load(reader);
return BsonDocument.Parse(token.ToString());
}
public override void WriteJson(JsonWriter writer, BsonDocument value, JsonSerializer serializer)
{
writer.WriteRawValue(value.ToJson());
}
}
装饰你的类型:
public class Child
{
public int Id { get; set; }
public string Type { get; set; }
[JsonConverter(typeof(BsonToJsonConverter))]
public BsonDocument Properties { get; set; }
}