You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core 6 Web API存在数据时返回404,动态属性序列化异常排查

问题分析与解决方案

问题背景

基于MongoDB和.NET Core 6开发的API接口出现异常:当数据库存在匹配数据时返回404错误,无匹配数据时可正常返回提示。经排查,问题根源在于JSON序列化环节,具体出在实体类的dynamic类型属性UserDocument的序列化过程中,且序列化出错时无明显错误日志或异常跟踪信息。

控制器代码

[HttpPost("FilterUsers")]
public async Task<IActionResult> gUsersFiltered([FromBody] gFilterRequest gr)
{
    if (gr.Key.Equals("Email"))
    {
        var users = await Task.Run(() => _gRepo
       .FilterBy(x => x.Email.Equals(gr.Value)).AsQueryable());
        return Ok(users);
    }
}

实体类相关属性

[BsonElement("UserDocument")]
public dynamic UserDocument { get; set; };

问题原因

当数据库存在数据时,API需要序列化包含UserDocument属性的实体对象:

  • 由于使用MongoDB驱动,dynamic类型的UserDocument实际会被反序列化为BsonDocument类型
  • .NET Core默认的System.Text.Json序列化器无法直接处理BsonDocument,序列化时会抛出未捕获的异常
  • 该异常未被正确捕获处理,导致ASP.NET Core请求流程中断,最终返回不符合预期的404错误(通常是异常处理中间件配置问题导致错误码显示异常)

解决方案

方案1:替换dynamic为具体实体类

如果UserDocument有固定数据结构,直接定义对应的实体类替代dynamic,让序列化器能正常处理:

// 定义UserDocument实体类
public class UserDocument
{
    public string DocumentName { get; set; }
    public DateTime CreateTime { get; set; }
    // 补充其他实际属性
}

// 修改实体类属性
[BsonElement("UserDocument")]
public UserDocument UserDocument { get; set; };

方案2:改用Newtonsoft.Json(Json.NET)处理序列化

Json.NET对MongoDB的BsonDocument支持更完善,步骤如下:

  1. 安装NuGet包:Microsoft.AspNetCore.Mvc.NewtonsoftJson
  2. 在Program.cs中配置替换默认序列化器:
builder.Services.AddControllers()
    .AddNewtonsoftJson(options =>
    {
        options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
    });

方案3:忽略该属性的序列化

如果前端不需要UserDocument数据,直接标记该属性忽略序列化:

[BsonElement("UserDocument")]
[JsonIgnore] // 使用System.Text.Json的特性,若用Json.NET则用[Newtonsoft.Json.JsonIgnore]
public dynamic UserDocument { get; set; };

方案4:自定义System.Text.Json转换器

编写自定义转换器处理BsonDocument的序列化/反序列化:

public class BsonDocumentConverter : JsonConverter<BsonDocument>
{
    public override BsonDocument Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        using var jsonDoc = JsonDocument.ParseValue(ref reader);
        return BsonDocument.Parse(jsonDoc.RootElement.GetRawText());
    }

    public override void Write(Utf8JsonWriter writer, BsonDocument value, JsonSerializerOptions options)
    {
        var jsonStr = value.ToJson();
        writer.WriteRawValue(jsonStr);
    }
}

然后在Program.cs中注册转换器:

builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.Converters.Add(new BsonDocumentConverter());
    });

辅助排查步骤

开启详细日志以捕获序列化时的具体错误:
在appsettings.json中调整日志级别:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning",
      "System.Text.Json": "Debug"
    }
  }
}

内容的提问来源于stack exchange,提问作者skillworks

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 13:05:55