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

应用重启后EF Core操作MongoDB时List的Bson反序列化错误

问题描述

我正在开发一个基于C#、带身份认证的ASP.NET Core项目,使用MongoDB.Driver和MongoDB.EntityFrameworkCore。尝试将用户ID以字符串形式存入购物车,并通过该ID查询购物车。添加商品后首次访问购物车页面调用Get方法可正常查询;但重启应用、重新登录后再次访问时,调用FirstOrDefaultAsync方法会触发Bson反序列化错误:

BsonSerializationException: Unknown discriminator value 'List`1'.

GetItems方法代码

public async Task<CartDto> GetItems()
{
    var user = signInManager.Context.User.Identity;
    if (user is not null && user.IsAuthenticated)
    {
        var identity = System.Security.Claims.ClaimTypes.NameIdentifier;
        var userId = signInManager.Context.User.FindFirst(identity)?.Value;

        var userCart = await context.Cart.FirstOrDefaultAsync(c => c.UserId == userId);
        if (userCart is not null)
        {
            CartDto cartDto = new()
            {
                Id = userCart.Id.ToString(),
                UserId = userCart.UserId,
                Products = userCart.Products
            };
            return cartDto;
        }
    }
}

Cart实体类定义

[Collection("Cart")]
public class Cart
{
    public ObjectId Id { get; set; }
    public required string UserId { get; set; }
    public List<string> Products { get; set; }
}
解决方案

这个错误源于MongoDB EntityFramework Core序列化List<string>时错误添加了鉴别器字段,重启应用后反序列化无法识别该值。以下是具体解决步骤:

  • 配置序列化规则:在DbContext的OnModelCreating方法中,为Cart集合的Products属性禁用鉴别器:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
    modelBuilder.Entity<Cart>(entity =>
    {
        entity.Property(c => c.Products)
              .HasElementName("Products")
              .HasConversion(
                  v => v,
                  v => BsonSerializer.Deserialize<List<string>>(BsonArray.Create(v))
              );
    });
}

若直接使用MongoDB.Driver,可在启动时注册序列化器:

BsonSerializer.RegisterSerializer(typeof(List<string>), new EnumerableSerializerBase<List<string>, string>(new StringSerializer()));
  • 清理旧数据:MongoDB中已存在的Cart文档带有错误的鉴别器字段,需手动删除这些旧文档,或更新Products字段移除_t鉴别器属性。

  • 初始化集合属性:在Cart类中为Products属性添加默认初始化,避免空引用问题:

public List<string> Products { get; set; } = new List<string>();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 18:07:26