在ViewBag中存储匿名对象

one*_*mer 19 c# reflection anonymous-types viewbag asp.net-mvc-3

这可能是一个愚蠢的问题,但我试图ViewBag像这样填充一个匿名对象:

ViewBag.Stuff = new { Name = "Test", Email = "user@domain.com" };
Run Code Online (Sandbox Code Playgroud)

并从这样的视图访问它:

@ ViewBag.Stuff.Name

我理解ViewBag是动态的,"Stuff"是一个匿名对象...但是当我从上面的View行看调试器时,我可以看到具有正确值的所有属性.为什么模型活页夹有这么难?

有没有一个很好的方法来实现这个而不创建一个模型类?我想继续使用new {}

SoW*_*Lie 9

基本上问题是匿名类型是作为内部生成的(请参阅答案),从View中无法对对象的属性进行硬类型引用.本文提供了更详细的解释:

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

使用动态匿名包装类(@Dakill的答案)可以实现,但是快速变得丑陋并且应该让程序员质疑为什么他/她会这样做.


Not*_*ble 5

与流行的看法相反,这可以做到,但涉及一个有点丑陋的黑客攻击将导致维护问题.它涉及编写一个类来"封装"您的匿名对象到动态对象.我前段时间做过一个练习,下面是包装类的代码,你会喜欢它ViewBag.Stuff = new DynamicAnonymous(new { Name = "Test", Email = "user@domain.com" });.

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);
            }                
 }
Run Code Online (Sandbox Code Playgroud)