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

ASP.NET Core 3 MVC CRUD应用MongoDB ObjectId反序列化报错

解决MongoDB反序列化错误:Cannot deserialize a 'ObjectId' from BsonType 'Double'

这个错误的核心原因很直白:你的MongoDB集合Customers里的_id字段存的是Double(数字)类型,但你在Customer模型里把Id属性标记为[BsonId]并定义成ObjectId类型,两者类型不匹配,自然就触发反序列化失败了。下面给你几种针对性的解决方案:

方案1:让MongoDB自动生成ObjectId类型主键

如果业务逻辑允许用MongoDB默认的ObjectId作为主键,只需要确保插入数据时不手动给Id赋值,让Mongo自动生成即可,同时修正现有数据的_id类型:

步骤1:保留现有模型定义

你的Customer模型本身没问题,继续沿用:

public class Customer {
    [BsonId]
    public ObjectId Id { get; set; }
    [BsonElement]
    public int CustomerID { get; set; }
    [BsonElement]
    public string Name { get; set; }
    [BsonElement]
    public int Age { get; set; }
    [BsonElement]
    public int Salary { get; set; }
}

步骤2:修正插入数据逻辑

插入新客户时,不要手动设置Id,MongoDB会自动为_id生成合法的ObjectId:

public IActionResult Insert(Customer customer)
{
    // 无需手动赋值Id,Mongo会自动生成
    collection.InsertOne(customer);
    TempData["Message"] = "Customer added successfully";
    return RedirectToAction("Index");
}

步骤3:修正现有错误格式数据(如果已存在)

如果集合里已经有_id为Double类型的数据,可以通过MongoDB Shell执行命令转换类型(执行前记得备份数据):

db.Customers.find({_id: {$type: 1}}).forEach(function(doc) {
    db.Customers.updateOne(
        {_id: doc._id},
        {$set: {_id: ObjectId()}}
    );
});

方案2:改用CustomerID作为主键(适合业务需要数字主键的场景)

如果你的业务逻辑要求用CustomerID作为主键,直接把[BsonId]标记转移到CustomerID属性上即可,同时调整关联代码:

步骤1:修改Customer模型

public class Customer {
    [BsonId] // 将主键标记转移到CustomerID
    public int CustomerID { get; set; }
    // 移除原ObjectId类型的Id属性(不需要的话直接删除)
    public string Name { get; set; }
    public int Age { get; set; }
    public int Salary { get; set; }
}

步骤2:调整视图和Controller的路由参数

因为主键变成了CustomerID,视图里的编辑/删除链接要同步修改:

<td>
    <a asp-controller="Home" asp-action="Update" asp-route-id="@item.CustomerID">Edit</a>
</td>
<td>
    <a asp-controller="Home" asp-action="Delete" asp-route-id="@item.CustomerID">Delete</a>
</td>

同时Controller里的Update/Delete方法要接收int类型的id参数,而非ObjectId:

public IActionResult Update(int id)
{
    var customer = collection.Find(c => c.CustomerID == id).FirstOrDefault();
    return View(customer);
}

方案3:临时兼容多种类型(不推荐,仅应急用)

如果暂时无法修改数据或模型,可以用BsonRepresentation特性尝试兼容不同类型,但这种方式存在潜在风险,仅作为临时过渡方案:

public class Customer {
    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)] // 尝试兼容ObjectId与数字/字符串类型
    public string Id { get; set; }
    // 其他属性保持不变
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:24:22