20

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

ViewBag.Stuff = new { Name = "Test", Email = "user@domain.com" };

并像这样从视图中访问它:

@ViewBag.Stuff.Name

我知道 ViewBag 是动态的,并且“Stuff”是一个匿名对象......但是当我从上面的 View 行中使用调试器查看时,我可以看到所有具有正确值的属性。为什么模型活页夹会遇到这样的困难?

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

4

4 回答 4

10

本质上,问题是匿名类型是作为内部生成的(请参阅答案),使得从视图中对对象属性的硬类型引用是不可能的。这篇文章提供了更详细的解释:

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

可以使用动态匿名包装类(@Dakill 的回答)来完成,但会很快变得丑陋,并且应该让程序员质疑他/她为什么要这样做。

于 2012-01-23T23:47:36.413 回答
5

与普遍的看法相反,这是可以做到的,但涉及到一些丑陋的 hack,这将导致以后的维护问题。它涉及编写一个类来将您的匿名对象“包装”成一个动态对象。前段时间我把它作为一个练习,下面是包装类的代码,你可以像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);
            }                
 }
于 2012-01-24T01:03:57.680 回答
2

我们可以使用 Json 来完成它

控制器:对象-> json 字符串,视图:Json 字符串-> 对象

场景只是控制器类将 C# 对象序列化为 json 字符串,然后视图接收此字符串并将其反序列化为对象,如下所示:

在控制器中:

using Newtonsoft.Json;
ViewBag.Stuff = JsonConvert.SerializeObject(new { Name = "Test", Email = "user@domain.com" });

在视图中:

@using Newtonsoft.Json
<p>@JsonConvert.DeserializeObject(ViewBag.Stuff).Name</p>

注意:这是在 Asp.Net Core 2.2 中测试的,检查该链接以安装Newtonsoft.Json

于 2019-01-13T20:29:59.130 回答
0

您可以使用所描述的机制 NothingsImpossible 来完成此操作,但无需使用 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;
于 2017-01-27T08:28:47.260 回答