I've got an MVC project with a partial page that looks somewhat like this:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<dynamic>" %>
<div class="tab-window <%= Model.TargetClass %> <%= Model.TargetTab == Model.SelectedTab ? "selected" : "" %>"
data-window-url="/SomeUrl/Partial/<%= Model.TargetTab %>/"
<%= Model.TargetTab == Model.SelectedTab ? "data-content-loaded=\"true\"" : "" %>>
<% if (Model.TargetTab == Model.SelectedTab) {
Html.RenderPartial(Model.TargetTab as string, Model.Model as object);
} %>
</div>
What it does is open another partial (the one named in Model.TargetTab
) with Model.Model
if it's the currently visible tab, otherwise just renders an empty div (which is loaded with jQuery when needed).
It's called like this:
<% Html.RenderPartial("TabWindowContainer", new { TargetTab = "MyTabName", TargetClass = "my-tab-class", SelectedTab = Model.Tab, Model = Model }); %>
This used to work.
Then I changed the value that goes into the Model
, and it stopped working. I changed it back, and it's still not working. To be clear, hg status currently doesn't show any of these files.
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'object' does not contain a definition for 'TargetClass'
When you try to open Model
in the Quickwatch window you see it has all the properties setup with correct values
But when you try to view any property, you get the same exception as before
Thinking about it, I realized that possibly, this shouldn't work at all; the object we're trying to access is from a different assembly so we wouldn't see its properties. But then, why did it use to work? I still have a running version where this works. What can I do to make it work again?
Update: It should work; the model is coming from another view in the same assembly, not from the controller.
Your dynamic type can't find the properties within the anonymous type because the anonymous type's properties are internal (not public). Thus, your app throws an exception even thought the anonymous type's properties are plainly visible to the debugger. Reference.
Create an Expando extension method.
public static ExpandoObject ToExpando(this object anonymousObject)
{
IDictionary<string, object> anonymousDictionary = new RouteValueDictionary(anonymousObject);
IDictionary<string, object> expando = new ExpandoObject();
foreach (var item in anonymousDictionary)
expando.Add(item);
return (ExpandoObject)expando;
}
Apply the extension as so.
<% Html.RenderPartial("TabWindowContainer", new { TargetTab = "MyTabName", TargetClass = "my-tab-class", SelectedTab = Model.Tab, Model = Model }.ToExpando()); %>
Hopefully, this will work and I didn't embarrass myself by misunderstanding the issue.
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