MongoDB .FindSync()结果无法序列​​化

时间:2016-06-23 03:45:07

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

尝试使用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);

    }

}

}

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

  

http://localhost:49270/api/Patients/5768a6f48200fa07289c93e8   类型   &#39; MongoDB.Driver.Core.Operations.AsyncCursor`1 [PatientData.Models.Patient]&#39;   无法序列化。考虑用它标记它   DataContractAttribute属性,并标记其所有成员   想要使用DataMemberAttribute属性进行序列化。如果类型是   一个集合,考虑用它来标记它   CollectionDataContractAttribute。请参阅Microsoft .NET Framework   其他支持类型的文档。

如果退回的类型是&#34;患者&#34;不是&#34; HttpResponseMessage&#34;,并使用

return (Patient)thePatient;

运行时异常更有趣:

  

&#39; System.InvalidCastException   无法转换类型&#39; MongoDB.Driver.Core.Operations.AsyncCursor`1 [PatientData.Models.Patient]&#39;输入&#39; PatientData.Models.Patient&#39;。

如果光标输入 PatientData.Models.Patient ,为什么不能成为那种类型?

这是基于Scott Allen的ASP.NET MVC 5 Fundamentals,WebAPI 2,ID by Query。他使用1.x驱动程序

我的是:

  • mongo server 3.2,64位
  • mongo C#driver 2.2.4

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

在版本2.x驱动程序中,Find()消失,有FindAsync()和FindSync(),两者都返回可能包含多个游标的游标。因此它就像string []不是一个字符串,这就是运行时错误所抱怨的。 幸运的是有一些名为&#34; extension&#34;。就我而言,只需附加

即可
.FirstOrDefault()

使它像这样

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