在MVC中使用动态匿名对象的RuntimeBinderException

con*_*tor 11 c# dynamic asp.net-mvc-3

代码

我有一个MVC项目的部分页面看起来像这样:

<%@ 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>
Run Code Online (Sandbox Code Playgroud)

它的作用是打开另一个部分(名为in Model.TargetTab),Model.Model如果它是当前可见的选项卡,否则只需渲染一个空div(在需要时加载jQuery).

它被称为这样:

<% Html.RenderPartial("TabWindowContainer", new { TargetTab = "MyTabName", TargetClass = "my-tab-class", SelectedTab = Model.Tab, Model = Model }); %>
Run Code Online (Sandbox Code Playgroud)

这曾经工作过.

然后我改变了进入的值,Model它停止了工作.我改回来了,它仍然无法正常工作.要清楚,hg status当前不显示任何这些文件.

例外

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'object' does not contain a definition for 'TargetClass'

当您尝试Model在Quickwatch窗口中打开时,您会看到它具有正确值的所有属性设置

快速监视

但是当您尝试查看任何属性时,您将获得与以前相同的异常

除了快速监视

考虑到这一点,我意识到这可能根本不起作用; 我们试图访问的对象来自不同的程序集,因此我们不会看到它的属性.但是,为什么它用于工作?我还有一个正在运行的版本.我该怎么做才能让它再次发挥作用?

更新:它应该工作; 模型来自同一装配体中的另一个视图,而不是来自控制器.

Eri*_* W. 8

您的动态类型无法在匿名类型中找到属性,因为匿名类型的属性是内部的(不是公共的).因此,即使调试器明显看到匿名类型的属性,您的应用程序也会抛出异常.参考.

创建一个Expando扩展方法.

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;
            }
Run Code Online (Sandbox Code Playgroud)

如此应用扩展名.

<% Html.RenderPartial("TabWindowContainer", new { TargetTab = "MyTabName", TargetClass = "my-tab-class", SelectedTab = Model.Tab, Model = Model }.ToExpando()); %>
Run Code Online (Sandbox Code Playgroud)

希望这会起作用,我并没有因为误解这个问题而使自己难堪.