2012-01-23 2 views
18

Это, вероятно, глупый вопрос, но я пытаюсь запихнуть анонимный объект в ViewBag так:Сохранение объекта Anonymous в ViewBag

ViewBag.Stuff = new { Name = "Test", Email = "[email protected]" }; 

и доступ к нему с видом, как так:

@ ViewBag.Stuff.Name

Я понимаю, что ViewBag динамичен и что «Stuff» является анонимным объектом ... но когда я смотрю с отладчиком из строки «Вид» выше, я могу видеть все свойства с соответствующими значениями , Почему такое связующее устройство моделирует с этим трудное время?

Есть ли хороший способ достичь этого, не создавая класс модели? Я хочу продолжить использовать new {}

+1

Вы можете использовать @ ViewBag.Stuff.Name или @ ViewBag.Stuff.Email ?? Причина Тест - это значение, а не ключ/свойство – SynerCoder

+0

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

+0

Оказывается, это невозможно. Смотрите это: http://stackoverflow.com/questions/5649536/entity-framework-select-new. – SoWeLie

ответ

7

По существу, проблема заключается в том, что анонимные типы генерируются как внутренние (see answer), что делает жесткие типизированные ссылки на свойство объекта невозможным из представления. В данной статье приводится более подробное объяснение:

http://www.heartysoft.com/anonymous-types-c-sharp-4-dynamic

Это можно осуществить с использованием класса-оболочки динамического Anonymous (@ ответ Dakill), но становится уродливым быстро и должен сделать программист вопрос, почему он/она сделает это.

+0

Я ищу ответ, если это можно сделать, а если нет, то почему ... (не уменьшал вас в сторону) –

+0

Итак, я дам вам еще один ответ. Тем не менее, я по-прежнему придерживаюсь этого ответа как то, что вы должны делать, если пытаетесь создать поддерживаемое приложение. – SoWeLie

5

Вопреки распространенному мнению, это может быть сделано, но связано с несколько уродливым взломом, который приведет к проблемам технического обслуживания в будущем. Он включает в себя запись класса, чтобы «обернуть» ваш анонимный объект в динамический объект. Я сделал это в качестве упражнения некоторое время назад, ниже приведен код класса-оболочки, вы бы использовать его как ViewBag.Stuff = new DynamicAnonymous(new { Name = "Test", Email = "[email protected]" }); ..

public class DynamicAnonymous : DynamicObject 
{ 
      object obj; 

      public DynamicAnonymous(object o) 
      { 
        this.obj = o; 
      } 

      public override IEnumerable<string> GetDynamicMemberNames() 
      { 
        return obj.GetType().GetProperties().Select(n => n.Name); 
      } 

      public override bool TryGetMember(GetMemberBinder binder, out object result) 
      { 
        var prop = obj.GetType().GetProperty(binder.Name); 
        if (prop == null) 
        { 
          result = null; 
          return false; 
        } 
        else 
        { 
          result = prop.GetValue(obj, null); 
          return true; 
        } 
      } 

      public override int GetHashCode() 
      { 
        return obj.GetHashCode(); 
      } 

      public override string ToString() 
      { 
        return obj.ToString(); 
      } 

      public override bool Equals(object obj2) 
      { 
        return obj.Equals(obj2); 
      }     
} 
+0

Благодарим вас за ответ. +1 для обеспечения работы. –

0

Вы можете сделать это с помощью механизма NothingsImpossible descibed, но withou реализации Вашего собственной оберткой с использованием ExpandoObject. Вот пример:

var items = _repository.GetItems() 
    .Select(og => { 
     dynamic eo = new System.Dynamic.ExpandoObject(); 
     eo.Id = item.Id; 
     eo.FriendlyName = og.FriendlyName; 
     eo.Selected = itemIds.Contains(item.Id); 
     return eo; 
    }) 
    .ToArray(); 
ViewBag.Items = items; 
Смежные вопросы