MVC Razordynamic模型中,'object'不包含'PropertyName'的定义

使用MVC 3和Razor视图引擎。 我有这个观点:

@model dynamic @{ var products = (List<ListItemBaseModel>)Model.Products; var threshold = (int)(Model.Threshold ?? 1); var id = Guid.NewGuid().ToString(); } 

这是从另一个视图使用此代码调用:

 @Html.Partial("PartialViewName", new { Products = Model, Threshold = 5 }) 

在这两个视图中,当我debugging他们,看模型,它似乎包含正确的对象。 当我执行代码时,我在“var products =”行上得到一个错误:

'object'不包含'Products'的定义

任何人都可以向我解释为什么我得到这个错误? 同样,当我在debugging模式下观看Model对象时,它看起来没事(有两个属性:Products和Threshold)

你传递一个匿名类的实例作为视图模型? 我只是尝试了这个(在CSHTML中的dynamic视图模型),并得到了与使用匿名类时相同的错误,但如果我创build一个命名的类,它工作得很好。 我search,但没有看到这个logging在任何地方。

 // error return View(new { Foo = 1, Bar = "test" }); // worked return View(new TestClass { Foo = 1, Bar = "test" }); 

编辑#1:

根据David Ebbo的说法 ,你不能将匿名types传递给dynamictypes的视图,因为匿名types被编译为internaltypes。 由于CSHTML视图被编译为一个单独的程序集,因此无法访问匿名types的属性。

编辑#2:

大卫·艾伯博(David Ebbo)在这篇文章中作了这样的解释:

注意(12/22/2011):现在,MVC 3直接支持dynamic,下面的技术不再是必要的。 这篇文章实际上是将这个function集成到MVC中的原因!

在.NET 4.0上匿名types可以很容易地转换为ExpandoObjects,因此所有的问题都可以通过转换本身的开销来解决。 看看这里

这与具有内部属性的匿名types无关

将匿名types从视图传递到局部视图是完全可能的

我今天遇到了同样的问题,对传递匿名types及其内在属性的问题没有任何(直接的)作用。

因此,就OP问题而言,@Lucas的答案是无关紧要的,即使解决方法可行

在OP的问题中,一个匿名types被从程序集X中的视图传递到程序集X中的一个部分 ,因此David Ebbo对匿名types的内部属性的概述是无关紧要的。 为视图编译的types,部分types和匿名types都包含在同一个程序集中

那么是什么原因导致突然的失败,从一个视图到一个局部的匿名types呢?

至less在我的情况下,我发现这是由于在相同的文件夹中另一个视图,指定了一个无法parsing的模型types 。 视图在运行时得到编译,因此在运行时编译视图失败也意味着无法编译dynamictypes,部分只会接收一个object 。 目前还不清楚发生了什么,但在OP的具体例子(和我的)中,这很可能是问题的原因。

有趣的是,如果模型types正确,但是视图的另一部分不能编译,匿名types不会以相同的方式受到影响。 这一定要归结到剃刀如何分解视图的组成部分的dynamic编译。

一旦你纠正了有问题的视图,重build整个解决scheme或清理并重build项目之前检查,看看它是否是固定的。

为了确保你不会被这个问题所csproj ,你可以通过将你的Razor视图编译到你的csproj文件来编译时间:

 <PropertyGroup> <MvcBuildViews>true</MvcBuildViews> </PropertyGroup> 

在你的解决scheme的任何地方添加下面的类(使用系统命名空间,所以它可以使用,而无需添加任何引用) –

  namespace System { public static class ExpandoHelper { 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; } } } 

将模型发送到视图时,将其转换为Expando:

  return View(new {x=4, y=6}.ToExpando()); 

我不确定你是否得到这个错误,因为你没有实施解决方法。 我在局部视图中得到了同样的错误。 解决scheme只是清理构build并重build它。 如果语法正确,代码应该可以正常工作,但是razor引擎可能不会正确地更新代码更改。

而不是在部分视图中使用dynamic模型types。

您可以使用@ViewData.Eval("foo")而不是@Model.foo来调用匿名对象属性。

然后,您可以从视图中删除@Model dynamic

我最近遇到这个问题时,通过Facebook的社会评论集成的意见之间传递一些属性。 示例代码:

 Html.RenderPartial(@"Layouts/Partials/_Comments", new {currentUrl = Model.CurrentPage.GetAbsoluteUrl(), commentCount = 5 }); 

然后在我看来,我只是有这个div:

 <div class="fb-comments" data-href="@ViewData.Eval("currentUrl")" data-numposts="@ViewData.Eval("commentCount")" data-width="100%"></div> 

要使用dynamictypes,您需要引用Microsoft.CSharp程序集