Подтвердить что ты не робот

RuntimeBinderException с динамическими анонимными объектами в MVC

Код

У меня есть проект 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

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

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

4b9b3361

Ответ 1

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

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

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