开发者

RuntimeBinderException with dynamic anonymous objects in MVC

The code

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.

The exception

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

RuntimeBinderException with dynamic anonymous objects in MVC

But when you开发者_如何学运维 try to view any property, you get the same exception as before

RuntimeBinderException with dynamic anonymous objects in MVC

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜