Tried to build a simple WebAPI with MongoDB, returns a Patient document based on value of _id.
Definition of 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; }
}
}
Database mongodb access, 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 controller:
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);
}
}
}
Compiled ok, got run-time exception, for example, URL
http://localhost:49270/api/Patients/5768a6f48200fa07289c93e8 Type 'MongoDB.Driver.Core.Operations.AsyncCursor`1[PatientData.Models.Patient]' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. If the type is a collection, consider marking it with the CollectionDataContractAttribute. See the Microsoft .NET Framework documentation for other supported types.
If returned type is "Patient" not "HttpResponseMessage", and use
return (Patient)thePatient;
run-time exception is more interesting:
'System.InvalidCastException Unable to cast object of type 'MongoDB.Driver.Core.Operations.AsyncCursor`1[PatientData.Models.Patient]' to type 'PatientData.Models.Patient'.
If the cursor is typed as PatientData.Models.Patient, why can't be that type?
This is based on Scott Allen's ASP.NET MVC 5 Fundamentals, WebAPI 2, Query by ID. He's using 1.x driver
Mine is:
- mongo server 3.2, 64-bit
- mongo C# driver 2.2.4