Return BsonDocument in ApiController Return BsonDocument in ApiController mongodb mongodb

Return BsonDocument in ApiController


I encountered this problem too, I took the Bson data, iterated through it converting each document to json at the Web API end, as I presume you did, creating a list of json strings - I sent this back and deserialized each string back to a Bson Document:

List<string> data = response.Content.ReadAsAsync<List<string>>().Result;List<BsonDocument> docList = new List<BsonDocument>();foreach (string dataStr in data) {    BsonDocument doc = MongoDB.Bson.Serialization.BsonSerializer.Deserialize<BsonDocument>(dataStr);    docList.Add(doc);                 }

Which I found in this post: Convert string into MongoDB BsonDocument

Bit ham fisted, but it works.


Presumably you have a schema associated with your application and the resource your api controller is attempting to return. By forcing it to use json, you are ignoring many of the benefits of the WebApi by completely sidestepping content negotiation. What if your client wants xml or yaml or ...

The issue you are experiencing is that WebApi doesn't know how to serialize a BsonDocument. So, you could write a ModelBinder for it such that it knows how to deal with it. Alternatively, and alluding to my first paragraph, create strongly typed entity/resource classes and since both MongoDB and WebApi already know about these types, they'll be able to work with them natively.


I face the same thing and wanted to simplify the back-end code.

I found Support for dynamic is simply works since driver v2.0, early this year. Just replace BsonDocument with dynamic keyword like this:

public async Task<dynamic> GetAll(string collectionName){    //var collection = db.GetCollection<BsonDocument>(collectionName);    //var result = await collection.Find(new BsonDocument()).ToListAsync();    var collection = db.GetCollection<dynamic>(collectionName);    return await collection.Find(new BsonDocument()).ToListAsync();}

and also for insert:

var collection = db.GetCollection<dynamic>(collectionName);await collection.InsertManyAsync(new List<dynamic>(){    new    {        PointType = "Building",        Name = "My Place",        Location = GeoJson.Point(GeoJson.Position(lng, lat))    }});

It is really helpful to create migration script. However don't accept dynamic or 'anything' from client site.