MVC Razor dynamic model, 'object' does not contain definition for 'PropertyName'
Add the following class anywhere in your solution (use System namespace, so its ready to use without having to add any references) -
namespace System
{
public static class ExpandoHelper
{
public static ExpandoObject ToExpando(this object anonymousObject)
{
IDictionary<string, object> anonymousDictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(anonymousObject);
IDictionary<string, object> expando = new ExpandoObject();
foreach (var item in anonymousDictionary)
expando.Add(item);
return (ExpandoObject)expando;
}
}
}
When you send the model to the view, convert it to Expando :
return View(new {x=4, y=6}.ToExpando());
This has nothing to do with anonymous types having internal properties
It is perfectly possible to pass anonymous types from a view to a partial view
I encountered the same problem today and it was nothing (directly) to do with the problem of passing anonymous types and their inherent internal
properties.
As such, in relation to the OPs question, the answer by @Lucas is irrelevant - even though the workaround will work.
In the OPs question, an anonymous type is being passed from a view in assembly X to a partial in assembly X, therefore the problem that David Ebbo outlined of the properties being internal for anonymous types is of no consequence; the types compiled for the view, the partial and the anonymous type are all contained in the same assembly.
So what is causing the sudden failure to pass an anonymous type from a view to a partial?
At least in my situation, I discovered that it was due to having another view in the SAME FOLDER that specifies a model type that cannot be resolved. Views get compiled at runtime, and so it would make sense as a failure at runtime to compile the views would also mean a failure to compile the dynamic types and the partial would simply receive an object
. It's not immediately obvious what is going on, but in the OPs specific example (and mine) this is more than likely the cause of the problem.
It is interesting to note that if the model type is correct but another part of the view doesn't compile then anonymous types are not affected in the same way. This must be down to how Razor breaks up the dynamic compilation of the component parts of the view.
Once you correct the offending view, either rebuild the whole solution or clean and rebuild the project before checking to see if it's fixed.
To ensure you are not caught out by this again you can enable compile time compilation of your Razor views by adding this to your csproj
file:
<PropertyGroup>
<MvcBuildViews>true</MvcBuildViews>
</PropertyGroup>
Are you passing an instance of an anonymous class as the view model? I just tried this (dynamic view model in CSHTML) and got the same error as your when using an anonymous class, but it worked fine if I created a named class. I searched but haven't seen this documented anywhere.
// error
return View(new { Foo = 1, Bar = "test" });
// worked
return View(new TestClass { Foo = 1, Bar = "test" });
EDIT #1:
According to David Ebbo, you can't pass an anonymous type into a dynamically-typed view because the anonymous types are compiled as internal
. Since the CSHTML view is compiled into a separate assembly, it can't access the anonymous type's properties.
EDIT #2:
David Ebbo has edited his post with this clarification:
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!
On .NET 4.0 Anonymous types can easily be converted to ExpandoObjects and thus all the problems are fixed with the overhead of the conversion itself. Check out here