Background
.NET 4, C#, MVC3, using JsonFx to serialize and deserialize data. Base controller has been extended to intercept all requests and do the following:
- Get some JSON from a remote server.
- Run a LINQ query based on passed in keys (hero, body, footer).
- Return a generic model to the view.
This code works fine when running in a controller inheriting from the base controller, but when placed in the Base controller and called from an inherited controller, I get the following error:
Unable to cast object of type 'System.Linq.Expressions.ConstantExpression' to type 'System.Linq.Expressions.ParameterExpression'.
This is the offending line:
var queryHero = heroModel.ArrayItems().Where(o => o.DisplayName == keyHero);
Question
How do I avoid getting a type error when in the base controller? It’s the same code that runs fine in the inherited controller.
Thanks for your time.
Full Code
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;
}
}
Can’t be sure what it is that is NOT initializing on time in the
BaseController, but found a work-around.DISCLAIMER: I am on the same dev team as
boynamedjiband this solution may be suited the best for our particular situation. Having said that, the solution is worth posting, we feel, as it might help others who encounter this quirk.Solution
The solution was found in making use of a combination of
dynamictypes andExpandoObjectsthat are specific to C# 4.0, as well as theIDictionarytype.Supporting Models
Razor Usage