MVC 中动态匿名对象的 RuntimeBinderException

发布于 2024-11-04 21:27:03 字数 1642 浏览 0 评论 0原文

我有一个 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>

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

它的名称如下:

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

这曾经有效。

然后我更改了进入模型的值,它停止工作。我又改回来了,还是不行。需要明确的是, hg status 目前不显示任何这些文件。

例外情况

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

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

Quickwatch

但是当您尝试查看任何属性时,您会得到与之前相同的异常

Quickwatch with exception

仔细想想,我发现这可能根本不起作用;我们尝试访问的对象来自不同的程序集,因此我们看不到它的属性。但是,为什么它曾经有效呢?我还有一个可以运行的版本。我该怎么做才能让它再次工作?

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

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

Quickwatch

But when you try to view any property, you get the same exception as before

Quickwatch with exception

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

请帮我爱他 2024-11-11 21:27:03

您的动态类型无法找到匿名类型中的属性,因为匿名类型的属性是内部的(非公共的)。因此,即使匿名类型的属性对调试器来说是明显可见的,您的应用程序也会引发异常。 参考。

创建 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;
            }

照此应用扩展。

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

希望这会起作用,并且我不会因为误解这个问题而让自己感到尴尬。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文