Проблема с использованием метода ToExpando - PullRequest
3 голосов
/ 12 июля 2011

Привет, я пытаюсь использовать решение ToExpando, чтобы использовать анонимные классы в бритвенных представлениях. Я использую это решение -> Динамический анонимный тип в Razor вызывает 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

Что я сделал не так?

Ответы [ 4 ]

5 голосов
/ 12 июля 2011

Сначала необходимо вызвать .AsEnumerable() или .ToList(), чтобы заставить ToExpando запускаться на клиенте.

3 голосов
/ 12 июля 2011

Попробуйте:

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
}
1 голос
/ 19 сентября 2011

Хорошо, опираясь на первые два ответа, я добавил еще один метод расширения, которого я удивляюсь, которого здесь нет:

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();
0 голосов
/ 19 июля 2011

проблема HtmlHelper.AnonymousObjectToHtmlAttributes(), это замена '_' с '-' для имени свойства. Посмотрите на комментарий к методу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...