RuntimeBinderException с динамическими анонимными объектами в MVC - PullRequest
11 голосов
/ 02 мая 2011

Код

У меня есть проект 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.TargetTab) с Model.Model, если это видимая на данный момент вкладка, в противном случае просто визуализируется пустой div (который загружается при необходимости jQuery).

Он называется так:

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

Раньше это работало.

Затем я изменил значение, которое входит в Model, и оно перестало работать.Я изменил его обратно, и он все еще не работает.Чтобы быть понятным, статус hg в настоящее время не показывает ни один из этих файлов.

Исключение

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

Когда вы пытаетесь открыть Model в окне Quickwatch, вы видите, что у него есть всенастройки свойств с правильными значениями

Quickwatch

Но при попытке просмотра любого свойства вы получаете то же исключение, что и раньше

Quickwatch with exception

Думая об этом, я понял, что, возможно, это не должно работать вообще;объект, к которому мы пытаемся получить доступ, находится в другой сборке, поэтому мы не увидим его свойства.Но тогда почему он работал?У меня все еще есть работающая версия, где это работает.Что я могу сделать, чтобы заставить это работать снова?

Обновление: Это должно работать;модель исходит из другого вида в той же сборке, а не из контроллера.

1 Ответ

8 голосов
/ 13 июля 2012

Ваш динамический тип не может найти свойства в анонимном типе, потому что свойства анонимного типа являются внутренними (не общедоступными).Таким образом, ваше приложение создает исключение, даже если свойства анонимного типа явно видны отладчику. Ссылка.

Создайте метод расширения 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()); %>

Надеемся, это будет работать иЯ не смутился, неправильно поняв проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...