Passing anonymous objects to MVC views and accessing them using dynamic

Note (12/22/2011): now that MVC 3 has direct support for dynamic, the technique below is no longer necessary. This post is in fact what led to integrating the feature into MVC!

First, I’ll start with a little disclaimer: this post is not about whether using dynamic is better/worse than static typing.  Instead, it’s about making it more convenient to use dynamic if you choose to go that route.  Clearly, some people dislike dynamic, as you can see in the comments in that post from Phil Haack, and for the most part, all the key arguments for/against have been made.

So anyway, let’s proceed… Recently, a few people have experimented with extending their view pages from ViewPage<dynamic>.  The idea is to then be able to access model data using the more convenient dynamic syntax.  e.g. check out this thread on StackOverflow, as well as Phil’s post I mention above.

One limitation that people are hitting is that you can’t easily pass an anonymous object as your model, because anonymous types are internal.

What we’re trying to write

e.g. Let’s say we’re trying to write this code in the controller:

public class HomeController : Controller {
    public ActionResult Index() {
        return View(
            new {
                Message = "Welcome to ASP.NET MVC!",
                Date = DateTime.Now

Note that we’re passing an anonymous object as the model.  The main reason to do this is to avoid the need to create an explicit ViewModel type.  Obviously, that’s controversial, but it should be viewed more as a simpler alternative to writing

ViewData["Message"] = "Welcome to ASP.NET MVC!";
ViewData["Date"] = DateTime.Now;
return View();

And then you’d change your view to have Inherits="System.Web.Mvc.ViewPage<dynamic>", which ideally would let you write something like this:

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
    <h2><%: Model.Message %></h2>
        The date is <%: Model.Date %>


Which is simpler than having to dig things out of the view data dictionary through string indexing.

But the default dynamic binder won’t let us!

Unfortunately, if you try to run this code, it’ll blow up with this error: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: '<>f__AnonymousType1<string,System.DateTime>.Message' is inaccessible due to its protection level

The reason for this is that the anonymous type being passed in the controller in internal, so it can only be accessed from within the assembly in which it’s declared.  Since views get compiled separately, the dynamic binder complains that it can’t go over that assembly boundary.

But if you think about it, this restriction from the dynamic binder is actually quite artificial, because if you use private reflection, nothing is stopping you from accessing those internal members (yes, it even work in Medium trust).  So the default dynamic binder is going out of its way to enforce C# compilation rules (where you can’t access internal members), instead of letting you do what the CLR runtime allows.

Solution: write our own!

I’m not sure why it was designed this way, but the good news is that it’s easy to work around by writing our own custom DynamicObject which binds through private reflection!  I’ve written a couple posts that make use of custom DynamicObjects (find them here), and the basic concept is the same: given the name of a property, write whatever code you want to produce its value.

Here, we’re not only going to write a custom Dynamic Object, but also a custom DynamicViewPage that uses it.  And doing all this takes surprisingly little code.  Here is the full implementation:

public class DynamicViewPage : ViewPage {
    // Hide the base Model property and replace it with a dynamic one
    public new dynamic Model { get; private set; }

    protected override void SetViewData(ViewDataDictionary viewData) {

        // Create a dynamic object that can do private reflection over the model object
        Model = new ReflectionDynamicObject() { RealObject = ViewData.Model };

    class ReflectionDynamicObject : DynamicObject {
        internal object RealObject { get; set; }

        public override bool TryGetMember(GetMemberBinder binder, out object result) {
            // Get the property value
            result = RealObject.GetType().InvokeMember(
                BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,

            // Always return true, since InvokeMember would have thrown if something went wrong
            return true;

As you can see there is not that much to it: when we need to look up a property value, we use private reflection and that’s the end of it.

And now it all works!

Once we have this, all that’s left to do is use it as our base class for the view, e.g.

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="MvcHelpers.DynamicViewPage" %>

And we’re then able to write exactly what we wanted above in the controller and the view, without hitting any access issues.

The full VS2010 project is attached to this post.

Comments (26)

  1. David Ebbo says:

    @ali: sorry, this requires VS 2010 because it relies on the new C# dynamic feature which didn’t exist before.  Note that you can download VS 2010 Beta 2 for free if you’d like to try it.

  2. ali says:

    nop my bad to missed the dynamic keyword.

    thanks again for the great post .

  3. That is really cool. They should replace ViewData with this little gem. Great Job.

  4. Rangoric says:

    I agree with Khalid this would be awesome as the default.

  5. adefwebserver says:

    so can I apply this "dynamic goodness" to my MVVM structure in Silverlight is some way?

  6. Very cool.

    Instead of letting it throw an exception, I capture it and then display all the available properties in the exception message


    Depending on configuration I suppress the error and return empty string. (eg. for TempData)

  7. Sharbel says:

    Because this uses Reflection, is this going to result in a slower databinding?  This is certainly convenient compared to using ViewData and it’s inherit danger of typing the keys in incorrectly, but I worry that using reflection will result in performance degradation?

  8. David Ebbo says:

    @adefwebserver: I’m less familiar with Silverlight scenarios, but this technique is not specific to MVC, so I suspect that there are good ways to make use of C# 4.0 dynamic there as well.

  9. David Ebbo says:

    @Adam: yes, these are good suggestions. It probably makes sense to make the default behavior return empty string instead of throwing. Otherwise, dealing with optional data becomes tricky.

  10. David Ebbo says:

    @Sharbel: I haven’t done any perf measurement, so I don’t have hard numbers.  The reflection call will indeed be slower that the dictionary lookup.  However, it’s not clear whether this will result in measurable perf degradation of the overall request.  I would be interesting to try measuring it.

  11. WillSullivan says:

    Couldn’t you just InternalsVisibleTo the MVC dll?  You’d have to sign your assembly, of course…

  12. David Ebbo says:

    @WillSullivan: the difficult part is that the views are compiled on the fly, and you cannot predict what assembly they will be in. This makes it hard to put an InternalVisibleTo attribute on the main assembly.

    As an aside, I haven’t verified that this would allow the default binder to work, though it certainly would make sense.

  13. Jack says:

    A slight idea, but it may result in exception after deploy

  14. Cain O'Sullivan says:

    Another option here is to use the ExpandoObject, for example,

    your page would inherit;


    and in your controller;

    dynamic model = new ExpandoObject();

    model.Message = "Hello World";

    return View(model);

    The downside to the ExpandoObject is that it cant except properties during initialzation.

  15. David Ebbo says:

    @Jack: I’m not sure what you mean by ‘exception after deploy’.  Can you clarify?

  16. David Ebbo says:

    @Cain: yes, ExpandoObject is sort of the ‘standard’ approach, and it is certainly an option.  The main point of this post is that I really wanted to find a way to pass in regular C# anonymous objects, which doesn’t work without extra effort.

  17. Charlie says:

    Umm just use  Inherits="System.Web.Mvc.ViewPage<object>" and use the templating in MVC2.

    Also when using dynamic you cannot make an instance. EX. dynamic d = new dynamic(); \ is incorrect. Instead you have to use

    dynamic d = new Object();

    d.Name = "";

  18. David Ebbo says:

    @Charlie: I don’t see how MVC2 templating will help with dealing with anonymous objects.

    Also, you won’t be able to use dynamic as you describe, since you can’t add properties to Object.  Instead, look at ExpandoObject if you want to do this.

  19. Charlie says:

    Yes you can add Properties to an Object as long as you declare it initially with dynamic.

    Go try it, I use it all the time.

  20. David Ebbo says:

    @Charlie: I just tried the exact two lines you have above in a console app, and it blew up with: "’object’ does not contain a definition for ‘Name’".  Are you doing anything differently?

  21. Charlie says:

    @davidebb Im Installing Beta2 on my work machine, get back to you soon.

  22. Jay says:

    impromptu-interface generates and proxy the implements and interface on the fly that forwards calls using the dlr (including changing the context so that it works on anonymous types). Sure you'd have to create an interface and there is a small one time penalty the first time a proxy is created for a type/interface but otherwise for each property call it ends up being 1 virtual invocation + 1 dlr invocation vs 1 dlr invocation + 1 reflection invocation so it balances out pretty quickly since reflection is very slow and uncached. .…/impromptu-interface

  23. Dominik says:


    How to do it working in a ViewUserControl?


  24. David Ebbo says:

    @Dominik: MVC3 now directly supports dynamic, so the technique described here is no longer necessary.

  25. gattaca says:

    If you still maintain .Net1.1/2.0/3.5 projects,

    the technique is necessary…

  26. Sheo Narayan says:

    I was facing same problem and after few hours of struggled, I made it and shared it as an article. This solution is in ASP.NET 4+…/binding-views-with-anonymous-type-collection-in-aspnet-mvc

    Hope this will help someone.

Skip to main content