【问题标题】:MongoDB .FindSync() result can not be serializedMongoDB .FindSync() 结果无法序列​​化
【发布时间】:2016-06-23 03:45:06
【问题描述】:

尝试用 MongoDB 构建一个简单的 WebAPI,根据 _id 的值返回一个 Patient 文档。

患者定义,Patient.cs

namespace PatientData.Models
{
    public class Patient
    {
        [BsonElement("_id")]        
        [BsonRepresentation(BsonType.ObjectId)]     
        public string  Id { get; set; }

        public string  Name { get; set; }                   
        public ICollection<Medication> Medications { get; set; }    
    }
    public class Medication 
    {
        public string Name { get; set; }
        public int Doses { get; set; }
    }
}

数据库mongodb访问,PatientDB.cs

namespace PatientData.Models
{
    public static class PatientDB
    {
        static MongoClient client = new MongoClient("mongodb://localhost");
        static IMongoDatabase db = client.GetDatabase("Patients");

    public static IMongoCollection<Patient> Open()  
    {
        return db.GetCollection<Patient>("Patients");       
    }

    public static IQueryable<Patient> query()
    {
        return db.GetCollection<Patient>("Patients").AsQueryable<Patient>();       // .AsQueryable() is still availabe in driver version 2.# as an extension for collection. so .Any() is still available as well.
    }
}

}

API 控制器

namespace PatientData.Controllers
{

public class PatientsController : ApiController
{
    IMongoCollection<Patient> _patients;

    public PatientsController()
    {
        _patients = PatientDB.Open();
    }
    public IEnumerable<Patient> Get()
    {
        return _patients.Find<Patient>(_=>true).ToList();   
    }

    public HttpResponseMessage Get(string id)   
    {
        var theFilter = Builders<Patient>.Filter.Eq("Id", id);
        var thePatient = _patients.FindSync<Patient>(theFilter);      

        //return (Patient)thePatient;         

        return Request.CreateResponse(thePatient);

    }

}

}

编译ok,得到运行时异常,例如URL

http://localhost:49270/api/Patients/5768a6f48200fa07289c93e8 类型 'MongoDB.Driver.Core.Operations.AsyncCursor`1[PatientData.Models.Patient]' 不能序列化。考虑用 DataContractAttribute 属性,并标记您的所有成员 想要使用 DataMemberAttribute 属性进行序列化。如果类型是 一个集合,考虑用 集合数据合同属性。请参阅 Microsoft .NET 框架 其他受支持类型的文档。

如果返回类型是“Patient”而不是“HttpResponseMessage”,则使用

return (Patient)thePatient;

运行时异常更有趣:

'System.InvalidCastException 无法将“MongoDB.Driver.Core.Operations.AsyncCursor`1[PatientData.Models.Patient]”类型的对象转换为“PatientData.Models.Patient”类型。

如果光标键入为PatientData.Models.Patient,为什么不能是那个类型?

这是基于 Scott Allen 的 ASP.NET MVC 5 Fundamentals,WebAPI 2,按 ID 查询。他正在使用 1.x 驱动程序

我的是:

  • mongo 服务器 3.2,64 位
  • mongo C#驱动2.2.4

【问题讨论】:

    标签: c# mongodb asp.net-web-api


    【解决方案1】:

    FindSync&lt;&gt; 不返回单个对象。以下问题的答案也可能对您有所帮助。 Difference between Find and FindAsync

    【讨论】:

    • 这太棒了。我做的最简单的方法是var thePatient = _patients.FindSync&lt;Patient&gt;(theFilter);。我希望 Mongo 的 Doc 可以更详细地解释这一点。
    【解决方案2】:

    在 2.x 版驱动程序中,Find() 消失了,有 FindAsync() 和 FindSync(),两者都返回可能包含多个游标的游标。因此它就像 string[] 不是一个字符串,这就是运行时错误所抱怨的。 幸运的是,有一种叫做“扩展”的东西。在我的情况下,只需附加

    .FirstOrDefault()
    

    变成这样

    var thePatient = _patients.FindSync<Patient>(theFilter).FirstOrDefault();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-09
      • 2015-03-04
      • 2015-02-03
      • 2019-02-25
      • 2019-05-03
      • 2022-01-24
      相关资源
      最近更新 更多