.NET 6 API中MongoDB ObjectId序列化为字符串的实现方法
.NET 6 API 中MongoDB ObjectId列表序列化为字符串的实现方案
问题场景
实体定义如下,需要保留MongoDB实体中的ObjectId类型定义,同时让接口JSON输出时直接返回ObjectId的24位字符串格式,而非默认的内部属性拆解结构:
public class Tournament { public List<ObjectId> FriendsId { get; set; } }
默认序列化输出结构(不符合预期):
{"FriendsId":[{"timestamp":1654717093,"machine":540378,"pid":-19594,"increment":6387934,"creationTime":"2022-06-08T19:38:13Z"},...]}
期望输出结构(注意示例中字符串外层多余的大括号为笔误,数组内直接存储字符串值即可):
{"FriendsId":["62a0f94f185b87a1a88c2354",...]}
具体实现
根据项目使用的JSON序列化器选择对应方案即可,两种方案都不会修改实体层的ObjectId类型定义,不影响MongoDB的正常读写映射。
方案1:使用.NET 6默认的System.Text.Json序列化器
- 编写ObjectId专属的JSON类型转换器
using MongoDB.Bson; using System.Text.Json; using System.Text.Json.Serialization; public class ObjectIdJsonConverter : JsonConverter<ObjectId> { public override ObjectId Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { string idStr = reader.GetString(); return string.IsNullOrWhiteSpace(idStr) ? ObjectId.Empty : ObjectId.Parse(idStr); } public override void Write(Utf8JsonWriter writer, ObjectId value, JsonSerializerOptions options) { writer.WriteStringValue(value.ToString()); } }- 在Program.cs中全局注册转换器,自动适配单个ObjectId和
List<ObjectId>类型的序列化、反序列化:
builder.Services.AddControllers() .AddJsonOptions(opt => { opt.JsonSerializerOptions.Converters.Add(new ObjectIdJsonConverter()); });方案2:使用Newtonsoft.Json序列化器(若项目已替换默认序列化器)
- 编写对应Newtonsoft版本的类型转换器
using MongoDB.Bson; using Newtonsoft.Json; public class ObjectIdNewtonsoftConverter : JsonConverter<ObjectId> { public override ObjectId ReadJson(JsonReader reader, Type objectType, ObjectId existingValue, bool hasExistingValue, JsonSerializer serializer) { string idStr = reader.Value?.ToString(); return string.IsNullOrWhiteSpace(idStr) ? ObjectId.Empty : ObjectId.Parse(idStr); } public override void WriteJson(JsonWriter writer, ObjectId value, JsonSerializer serializer) { writer.WriteValue(value.ToString()); } }- 在Program.cs中全局注册转换器:
builder.Services.AddControllers() .AddNewtonsoftJson(opt => { opt.SerializerSettings.Converters.Add(new ObjectIdNewtonsoftConverter()); });
配置完成后重启项目,接口输出就会自动把ObjectId转为字符串格式,同时反序列化时也能自动把前端传入的字符串ID转为ObjectId类型,不需要额外做类型转换。
内容的提问来源于stack exchange,提问作者danilonet
相关产品推荐
相关产品推荐

