.NET 4,C#,MVC3,使用JsonFx来序列化和反序列化数据。基本控制器已扩展为拦截所有请求并执行以下操作:
此代码在从基本控制器继承的控制器中运行时工作正常,但是当放置在基本控制器中并从继承的控制器调用时,我收到以下错误:
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;
}
}
答案 0 :(得分:1)
无法确定在BaseController
中未按时完成初始化,但找到了解决办法。
免责声明:我与boynamedjib
在同一个开发团队中,此解决方案可能最适合我们的特定情况。话虽如此,我们觉得这个解决方案值得发布,因为它可能会帮助其他遇到这个怪癖的人。
在使用特定于C#4.0的dynamic
类型和ExpandoObjects
以及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>