【问题标题】:Problem with using a ToExpando method使用 ToExpando 方法的问题
【发布时间】:2011-10-03 18:45:00
【问题描述】:

您好,我尝试使用 ToExpando 解决方案在 razor 视图中使用匿名类。 我使用这个解决方案 -> Dynamic Anonymous type in Razor causes RuntimeBinderException

我会写我所做的:

  1. 我添加了一个文件 Extensions.cs 我在其中放置了以下代码:

    public static class Extensions
    {
        public static ExpandoObject ToExpando(this object anonymousObject)
        {
            IDictionary<string, object> anonymousDictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(anonymousObject);
            IDictionary<string, object> expando = new ExpandoObject();
            foreach (var item in anonymousDictionary)
                expando.Add(item);
            return (ExpandoObject)expando;
        }
    }
    
  2. 我在控制器方法中编写了一个从数据库接收元组的查询:

    IEnumerable<dynamic> articles = (from p in db.Articles.Where(p => p.user_id == 2)
            select new
            {
                p.article_id,
                p.title,
                p.date,
                p.category,
                AverageScore = db.Articles_Scores
                    .Where(o => o.user_id == p.user_id && p.article_id == o.article_id)
                    .Average(m => m.score)
            }).AsEnumerable()
              .Select(r => r.ToExpando());
    int ii = 0;
    foreach(var it in articles) {
        // HERE I CAN READ EVERYTHING
        ii = it.article_id;
    }
    return View(articles);
    
  3. 在视图中我声明了一个模型:

    @model IEnumerable<dynamic>
    
  4. 我尝试获取每个元组:

    @foreach (dynamic item in Model) {
    // some code
        @item.article_id // HERE IS EXCEPTION
    }
    

在 foreach 行中我遇到了异常:

RuntimeBinderException“System.Dynamic.ExpandoObject”不包含“article_id”的定义

我做错了什么?

【问题讨论】:

  • 你没有展示的是实际调用ToExpando的代码。
  • 对不起,我忘了。现在我更新了。

标签: asp.net-mvc linq entity-framework asp.net-mvc-3 razor


【解决方案1】:

好的,在前两个答案的基础上,我添加了另一种扩展方法,我很惊讶我在这里没有看到:

public static List<ExpandoObject> ToExpandoList<T>(this IEnumerable<T> ie) {
    return ie.Select(o => o.ToExpando()).ToList();            
}

现在在我看来,我有这样的代码,并且使用 Razor 可以正常工作。

var peoples = from f in "tom dick susan roberto".Split(' ') 
              select new { FirstName = f, Age = f.Length };
ViewBag.People = peoples.ToExpandoList();

【讨论】:

  • linq.ToExpando().ToList() 对我不起作用,但您的 .ToExpandoList() 助手成功了。
【解决方案2】:

问题是HtmlHelper.AnonymousObjectToHtmlAttributes(),它正在替换 '_' 和 '-' 作为属性名称。查看方法的注释。

【讨论】:

    【解决方案3】:

    试试:

    dynamic articles = (from p in db.Articles.Where(p => p.user_id == 2_
                    select new
                    {
                        p.article_id,
                        p.title,
                        p.date,
                        p.category,
                        AverageScore = db.Articles_Scores
                            .Where(o => o.user_id == p.user_id && p.article_id == o.article_id)
                            .Average(m => m.score)
                    }).AsEnumerable()
                      .Select(r => r.ToExpando());
    

    编辑:确保声明 dynamic 而不是 var

    编辑 2:在您的 for 外观中,您再次声明 var。将其更改为:

    @foreach (dynamic item in Model) {
        // some code
        @item.article_id // HERE IS EXCEPTION
    }
    

    【讨论】:

    • 我遇到异常:RuntimeBinderException: 'System.Dynamic.ExpandoObject' 不包含 'article_id' 的定义
    • 感谢 Matthew 的帮助,但它仍然无法正常工作。我使用了 IEnumerable ,现在我使用了您的解决方案,但仍然存在同样的问题。这很奇怪......因为它在控制器方法中工作得很好(foreach 工作得很好,我可以读取每个属性)但是在 View(Razor) 中我得到了同样的例外。我真的不知道我做错了什么......
    • 我更新了我的帖子。查看 linq 查询下面的代码。我还通过评论检查了我遇到异常的地方。
    • 对我有用的是这样做......(来自......(选择新 {}).ToExpando()).ToList()。基本上,确保expando是在实际创建的对象上,而不是之后。以另一种方式(使用新选择)也可以,并且实际上可能看起来更干净。
    • Edit 1 非常重要,因为对象是在那里创建的。在我的情况下,不需要编辑 2,即 @foreach(模型中的 var 项)工作得很好
    【解决方案4】:

    您需要先调用.AsEnumerable().ToList() 以强制ToExpando 在客户端上运行。

    【讨论】:

    • 你的意思是我应该使用 ToExpando().AsEnumerable() 吗?如果是这样,我给出了一个类似的例外:/
    • 否;您需要调用AsEnumerable first 以便ToExpando 在客户端上运行
    • 好的。但是我遇到了一个异常:RuntimeBinderException:'System.Dynamic.ExpandoObject' 不包含'article_id'的定义
    猜你喜欢
    • 2012-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-26
    • 2014-01-16
    • 2018-12-30
    相关资源
    最近更新 更多