.NET Core Web API接收任意结构数据转换为BsonDocument的问题
解决ASP.NET Core API接收任意结构请求体并转为BsonDocument存储的问题
问题根源
你用Object作为请求参数时,ASP.NET Core的模型绑定会根据请求内容自动解析为string、数值类型或JsonElement/JObject,这些类型调用ToBsonDocument()无法生成符合预期的Bson结构,导致存储失败。
可行解决方案
方案1:直接读取原始请求体
绕过模型绑定,直接读取原始JSON内容并解析为BsonDocument,适配任意结构的请求体:
[HttpPost("InsertBsonUser")] public async Task<IActionResult> InsertBsonUser() { // 读取原始请求体 using var reader = new StreamReader(Request.Body); var requestBody = await reader.ReadToEndAsync(); // 将JSON字符串解析为BsonDocument var bsonDoc = BsonDocument.Parse(requestBody); // 插入MongoDB var dbClient = new MongoClient("mongodb://127.0.0.1:27017"); var db = dbClient.GetDatabase("Identity"); var users = db.GetCollection<BsonDocument>("Users"); await users.InsertOneAsync(bsonDoc); return Ok(bsonDoc); }
方案2:使用JsonElement接收请求体
利用JsonElement兼容任意JSON结构的特性,再转为BsonDocument:
[HttpPost("InsertBsonUserWithJsonElement")] public async Task<IActionResult> InsertBsonUserWithJsonElement([FromBody] JsonElement requestModel) { // 将JsonElement转为原始JSON字符串 var jsonStr = requestModel.GetRawText(); var bsonDoc = BsonDocument.Parse(jsonStr); // 插入MongoDB var dbClient = new MongoClient("mongodb://127.0.0.1:27017"); var db = dbClient.GetDatabase("Identity"); var users = db.GetCollection<BsonDocument>("Users"); await users.InsertOneAsync(bsonDoc); return Ok(bsonDoc); }
方案3:配置模型绑定直接支持BsonDocument
自定义JSON转换器,让模型绑定直接将请求体转为BsonDocument,代码更简洁:
首先添加自定义转换器:
public class BsonDocumentConverter : JsonConverter<BsonDocument> { public override BsonDocument Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { var jsonStr = JsonSerializer.Deserialize<string>(ref reader, options); return BsonDocument.Parse(jsonStr); } public override void Write(Utf8JsonWriter writer, BsonDocument value, JsonSerializerOptions options) { writer.WriteRawValue(value.ToJson()); } }
然后在Program.cs中配置:
builder.Services.AddControllers() .AddJsonOptions(options => { options.JsonSerializerOptions.Converters.Add(new BsonDocumentConverter()); });
最后编写API方法:
[HttpPost("InsertBsonUserDirect")] public async Task<IActionResult> InsertBsonUserDirect([FromBody] BsonDocument requestModel) { var dbClient = new MongoClient("mongodb://127.0.0.1:27017"); var db = dbClient.GetDatabase("Identity"); var users = db.GetCollection<BsonDocument>("Users"); await users.InsertOneAsync(requestModel); return Ok(requestModel); }
内容的提问来源于stack exchange,提问作者user2527732
相关产品推荐
相关产品推荐

