I'm working on an API in ASP.NET MVC 4, I'm using MongoDB as a backend.
Due to MongoDB storing and returning BSON objects, and MVC4 returning JSON objects, I figured that it would be rather easy to simply return the BSON on the rest calls.
This didn't work, so I found the .toJson()
method on th BsonDocument
class, converts the BSON object to a JSON-string representation. Unfortunately when I return this string through my ApiController
, MVC apparently thinks it should re-serialize the string as JSON, which the browser can't interpret.
So I would like to ask if there is a way to disable the JSON serialization for a specific ApiController
method?
My current workaround is to de-serialize the JSON returned from .toJson()
before returning it such that it will be serialized again, but this seems rather wasteful.
You can return one or the other, not both. Frankly, a WebAPI controller returns nothing but data, never a view page. A MVC controller returns view pages.
Web API 2.1 introduces support for BSON.
BSON stands for Binary Javascript Object Notation. It is a binary-encoded serialization of JSON documents. BSON has been extended to add some optional non-JSON-native data types, like dates and binary data.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With