使用ToExpando方法时出现问题

时间:2011-07-12 15:58:44

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

您好我尝试使用ToExpando解决方案在剃刀视图中使用匿名类。 我用这个解决方案 - > 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
    }
    
  5. 在foreach行中,我得到了一个例外:

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

    我做错了什么?

4 个答案:

答案 0 :(得分:5)

您需要先致电.AsEnumerable().ToList()以强制ToExpando在客户端上投放。

答案 1 :(得分: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
}

答案 2 :(得分: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();

答案 3 :(得分:0)

问题是HtmlHelper.AnonymousObjectToHtmlAttributes(),它正在取代 '_'带有' - '作为属性名称。查看该方法的注释。