Как мои ViewData могут быть нулевыми, но расширяемыми в отладчике? - PullRequest
7 голосов
/ 28 апреля 2011

Только что натолкнулся на интересный эффект при отладке View. Сценарий легко воспроизвести - у меня есть точка останова в View, в окне просмотра я добавляю ViewBag.ViewData и значение null. Однако, если я просто добавлю ViewBag и разверну объект, я смогу увидеть ViewData, а это не null. Я также могу успешно расширить его и увидеть его свойства.

Кто-нибудь может объяснить, является ли это ошибкой или причиной этого поведения?

ViewBag.ViewData in Watch window

EDIT

ViewBag.ViewData на самом деле null. Например. если у меня есть этот код в представлении:

if (ViewBag.ViewData == null)
{
    <span>ViewBag.ViewData is null</span>
}

отображает диапазон. Так что странная часть в том, что я могу развернуть его в окне просмотра и увидеть свойства.

EDIT2

В ответ на ответ @ Darin Dimitrov - я пытался воспроизвести это поведение с помощью пользовательского тестового класса и получаю RuntimeBinderException при попытке получить доступ к частной собственности: 'SomeClass.SomeProperty' is inaccessible due to its protection level:

public class SomeClass
{
    private string SomeProperty;
}

dynamic dynamicObject = new SomeClass();
if (dynamicObject.SomeProperty == null)
{
    Console.WriteLine("dynamicObject.SomeProperty is null");
}

В этом случае я не должен получать то же исключение при доступе к ViewBag.ViewData в представлении (строка с if (ViewBag.ViewData == null))?

Ответы [ 4 ]

6 голосов
/ 28 апреля 2011

В окне отладчика / просмотра вы видите private ViewData свойство ViewBag.Когда вы выполняете тест в представлении, вы, очевидно, не имеете доступа к этому приватному полю и получаете нулевое значение, потому что нет соответствующего открытого свойства.

Теперь выполните следующий тест в представлении:

@if (null == ViewBag
         .GetType()
         .GetProperty("ViewData", BindingFlags.Instance | BindingFlags.NonPublic)
         .GetValue(ViewBag, null)
)
{
    <span>ViewBag.ViewData is null</span>
}

и вы не увидите пролета.

Конечно, все это очень забавно, но когда речь идет о написании реального мира и правильно спроектированных приложений ASP.NET MVC, то и ViewData, и ViewBag имеютнет места.Эти двое являются моими худшими врагами в разработке приложений ASP.NET MVC.

Вывод: всегда используйте модели представлений и строго типизированные представления и получайте удовольствие.

0 голосов
/ 28 апреля 2011

Хотя ваш код всегда выполняется в пределах определенной области (класса, метода, частного и т. Д.), Отладчик не имеет таких ограничений

0 голосов
/ 28 апреля 2011

почему вы ссылаетесь на ViewBag.ViewData? Просто обратитесь к ViewData напрямую. Это может работать, потому что за кулисами viewbag использует viewdata, вы можете смотреть на внутреннее представление ViewData, отличное от вашего свойства dynamicimc в «ViewData»

После тестирования этого, ViewBag обнаруживается как непубличный член ... что я и ожидал. System.Web.Mvc.DynamicViewDataDictionary имеет закрытый член ViewData

0 голосов
/ 28 апреля 2011

У меня нет технического объяснения, но я считаю, что это потому, что ViewBag является динамическим. Это похоже на просмотр выражения, вы не видите содержимое набора результатов без запуска выражения.

Я полагаю, что ViewBag ведет себя так же, потому что вы переходите непосредственно к свойству, которое не было загружено, и делаете это через отладчик, он просто решает не загружать это свойство.

Я, конечно, могу ошибаться: D

Просто ради аргументов, он делает то же самое в быстром просмотре или в непосредственном окне?

...