Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

Im working on a project that use .NET Razor and mongodb. I would like to do something like this:

@{
    var feeds = DP.Database.GetCollection("feeds").FindAll();
}
<ul>
    @foreach (dynamic feed in feeds)
    {
        <li>@feed.message - @feed.from.name</li>
    }
</ul>

However, the current mongodb C# driver FindAll() return collection of BsonDocument which does not support dynamic object. Anybody know a .NET 4 dynamic supported mongodb C# driver?

Thanks a lot

share|improve this question
add comment (requires an account with 50 reputation)

3 Answers

up vote 7 down vote accepted

Currently, there is no support for dynamic in the MongoDB driver. This is because it is based on .NET 3.5. However, since a .NET 4.0 assembly can reference a .NET 3.5 assembly, it is possible for you to write a IBsonSerializationProvider and an IBsonSerializer in .NET 4.0 to support dynamics.

We, 10gen, are looking at doing this in the future. I have spiked some support at https://github.com/craiggwilson/mongo-csharp-driver/tree/dynamic if you want to take a look. There are most definitely bugs, but it shows that it is possible.

share|improve this answer
Thanks Craig, i found a way to make it work. check here groups.google.com/forum/?fromgroups#!topic/mongodb-user/… – hoang Apr 20 '12 at 4:46
Yes, I saw that. I will echo here for SO users. That works fine, but requires a low level modification to the core. The way I presented above is a side-load and accomplishes the same thing without modifying the core. Obviously, there are some differences, but it gets most of the way there. It is just a spike after all, so... – Craig Wilson Apr 20 '12 at 16:34
1  
Take a look at MongoDB.Dynamic. It uses MongoDB official driver and take an approach of using interfaces with dynamics of C# 4.0. – Jone John Polvora Jun 4 '12 at 20:49
add comment (requires an account with 50 reputation)

I created a straight-forward extension to the MongoDB driver that re-serializes the bson document using JSON.Net and deserializes it as a dynamic. By inlcuding the following class, you can simply convert your mongo queries to dynamic like this

dynamic obj = collection.FindOneByIdAs<BsonDocument>(someObjectId).ToDynamic();

Extension class:

public static class MongoDynamic
{
    private static System.Text.RegularExpressions.Regex objectIdReplace = new System.Text.RegularExpressions.Regex(@"ObjectId\((.[a-f0-9]{24}.)\)", System.Text.RegularExpressions.RegexOptions.Compiled);
    /// <summary>
    /// deserializes this bson doc to a .net dynamic object
    /// </summary>
    /// <param name="bson">bson doc to convert to dynamic</param>
    public static dynamic ToDynamic(this BsonDocument bson)
    {
        var json = objectIdReplace.Replace(bson.ToJson(), (s) => s.Groups[1].Value);
        return Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(json);
    }
}

Be sure to reference Newtonsoft.Json.dll (http://james.newtonking.com/projects/json-net.aspx)

share|improve this answer
add comment (requires an account with 50 reputation)

Just to build on Maximilian's answer. This will return a list of dynamics from any query.

    /// <summary>
    /// deserializes this BsonDocument cursor result to a list of .net dynamic objects
    /// </summary>
    /// <param name="cursor">cursor result to convert to dynamic</param>
    /// <returns></returns>
    public static List<dynamic> ToDynamicList(this MongoCursor<BsonDocument> cursor)
    {
        var dynamicList = new List<dynamic>();
        var list = cursor.ToList();
        for (int i = 0, l = list.Count; i < l; i++)
            dynamicList.Add(list[i].ToDynamic());

        return dynamicList;
    }
share|improve this answer
This seems redundant. You could just do cursor.Select(doc => doc.ToDynamic()). Add .ToList() if needed. In general, writing methods for which the framework already provides a good solution should be avoided. – Tomas Mar 25 at 15:23
add comment (requires an account with 50 reputation)

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.