Сбои базового контроллера MVC3, тот же код работает в унаследованном контроллере - PullRequest
1 голос
/ 12 января 2012

Фон

.NET 4, C #, MVC3, используя JsonFx для сериализации и десериализации данных.Базовый контроллер был расширен для перехвата всех запросов и выполнения следующих действий:

  1. Получение некоторого JSON с удаленного сервера.
  2. Запуск запроса LINQ на основе переданных ключей (герой, тело, нижний колонтитул).
  3. Возвращение универсальной модели в представление.

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

Unable to cast object of type 'System.Linq.Expressions.ConstantExpression' to type 'System.Linq.Expressions.ParameterExpression'.

Это неправильная строка:

    var queryHero = heroModel.ArrayItems().Where(o => o.DisplayName == keyHero);

Вопрос

Как избежать получения типаошибка когда в базовом контроллере?Это тот же код, который отлично работает в унаследованном контроллере.

Спасибо за ваше время.

Полный код

public models.GenericPageModel GetGenericPageContent(string keyHero, string keyBody, string keyFooter)
{
    try
    {
        // get content "tables"
        var heroContent = GetJson("Page_Section_Hero_Content");
        var bodyContent = GetJson("Page_Section_Body_Content");
        var footerContent = GetJson("Page_Section_Footer_Content");

        // new reader
        var reader = new JsonReader(new DataReaderSettings(new DataContractResolverStrategy()));

        // read it
        var heroModel = reader.Query<models.PageSectionHeroContent>(heroContent);
        var bodyModel = reader.Query<models.PageSectionBodyContent>(bodyContent);
        var footerModel = reader.Query<models.PageSectionFooterContent>(footerContent);

        // run query for current page
        var queryHero = heroModel.ArrayItems().Where(o => o.DisplayName == keyHero);
        var queryBody = bodyModel.ArrayItems().Where(o => o.DisplayName == keyBody);
        var queryFooter = footerModel.ArrayItems().Where(o => o.DisplayName == keyFooter);

        // models for return
        models.PageSectionHeroContent hero;
        models.PageSectionBodyContent body;
        models.PageSectionFooterContent footer;

        // any hero content?
        if (queryHero.Any())
            hero = new models.PageSectionHeroContent { DisplayName = queryHero.FirstOrDefault().DisplayName, 
                ContentXML = queryHero.FirstOrDefault().ContentXML };
        else
            hero = new models.PageSectionHeroContent { DisplayName = "Sorry, there was an error.", 
                ContentXML = "<details><error>No data was returned.</error></details>" };

        // any body content?
        if(queryBody.Any())
            body = new models.PageSectionBodyContent { DisplayName = queryBody.FirstOrDefault().DisplayName, 
                ContentXML = queryBody.FirstOrDefault().ContentXML };
        else
            body = new models.PageSectionBodyContent { DisplayName = "Sorry, there was an error.", 
                ContentXML = "<details><error>No data was returned.</error></details>" };

        // any footer content?
        if(queryFooter.Any())
            footer = new models.PageSectionFooterContent { DisplayName = queryFooter.FirstOrDefault().DisplayName, 
                ContentXML = queryFooter.FirstOrDefault().ContentXML };
        else
            footer = new models.PageSectionFooterContent { DisplayName = "Sorry, there was an error.", 
                ContentXML = "<details><error>No data was returned.</error></details>" };

        // build generic page model
        var model = new models.GenericPageModel { PageSectionHeroContent = hero, PageSectionBodyContent = body, PageSectionFooterContent = footer };

        return model;

    }
    catch (Exception ex)
    {   
        //todo: handle, log exception
        return null;
    }
}

1 Ответ

1 голос
/ 21 января 2012

Не могу быть уверен, что именно оно НЕ инициализируется вовремя в BaseController, но нашел обходной путь.

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Я нахожусь на том же устройствеTeam as boynamedjib, и это решение может быть лучше всего подходит для нашей конкретной ситуации.Сказав это, решение стоит опубликовать, мы считаем, что оно может помочь другим, кто сталкивается с этой причудой.

Решение

Решение было найдено при использовании комбинации dynamicтипы и ExpandoObjects, специфичные для C # 4.0, а также тип IDictionary.

 public models.GenericPageDataModel GetGenericPageContent(string keyHero, string keyBody, string keyFooter)
        {
            try
            {
                var pageData = new List<models.GenericPageData>
                             {
                                 new models.GenericPageData{Key = "HeroModel",Value = GetJson("pro_Page_Section_Hero_Content")},
                                 new models.GenericPageData{Key = "BodyModel",Value = GetJson("pro_Page_Section_Body_Content")},
                                 new models.GenericPageData{Key = "FooterModel",Value = GetJson("pro_Page_Section_Footer_Content")}
                             };

                var reader = new JsonReader();

                var model = new models.GenericPageDataModel();
                foreach (var p in pageData)
                {
                    var objList = new List<ExpandoObject>();
                    dynamic output = reader.Read(p.Value);
                    foreach (var h in output)
                    {
                        dynamic obj = new ExpandoObject();
                        foreach (dynamic o in h)
                        {
                            var item = obj as IDictionary<String, object>;
                            item[o.Key] = o.Value;
                        }
                        objList.Add(obj);
                    }
                    switch (p.Key)
                    {
                        case ("HeroModel"):
                            model.HeroModel = objList.FirstOrDefault(o => o.FirstOrDefault(i => i.Key.Equals("DisplayName")).Value.Equals(keyHero));
                            break;
                        case ("BodyModel"):
                            model.BodyModel = objList.FirstOrDefault(o => o.FirstOrDefault(i => i.Key.Equals("DisplayName")).Value.Equals(keyBody));;
                            break;
                        case ("FooterModel"):
                            model.FooterModel = objList.FirstOrDefault(o => o.FirstOrDefault(i => i.Key.Equals("DisplayName")).Value.Equals(keyFooter));;
                            break;
                        default:
                            break;
                    }
                }
                return model;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

Поддерживаемые модели

public class GenericPageData
        {
            public string Key { get; set; }
            public string Value { get; set; }
        }

        public class GenericPageDataModel
        {
            public ExpandoObject HeroModel { get; set; }
            public ExpandoObject BodyModel { get; set; }
            public ExpandoObject FooterModel { get; set; }
        }

Использование бритвы

@model my.project.com.Models.ContentModels.GenericPageDataModel        

@{
    ViewBag.Title = "My Title";
    Layout = "~/Views/Shared/_Layout.cshtml";

    ViewBag.heroDisplayName = @Model.HeroModel.ToDictionary(p => p.Key).FirstOrDefault(k => k.Key.Equals("DisplayName")).Value.Value;
}

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