Ruu*_*ier 104 razor asp.net-mvc-3
使用MVC 3和Razor视图引擎.我有这个观点:
@model dynamic
@{
var products = (List<ListItemBaseModel>)Model.Products;
var threshold = (int)(Model.Threshold ?? 1);
var id = Guid.NewGuid().ToString();
}
Run Code Online (Sandbox Code Playgroud)
使用此代码从另一个视图调用它:
@Html.Partial("PartialViewName", new { Products = Model, Threshold = 5 })
Run Code Online (Sandbox Code Playgroud)
在两个视图中,当我调试它们并观看模型时,它似乎包含正确的对象.当我执行代码时,我在"var products ="行上收到错误说:
'object'不包含'Products'的定义
任何人都可以向我解释为什么我会收到这个错误?再次,当我在调试模式下观察Model对象时,它看起来很好(具有2个属性:Products和Threshold)
Luc*_*cas 149
您是否将匿名类的实例作为视图模型传递?我刚试过这个(CSHTML中的动态视图模型),并且在使用匿名类时遇到了同样的错误,但如果我创建了一个命名类,它就可以正常工作.我搜索过,但没有看到任何记录.
// error
return View(new { Foo = 1, Bar = "test" });
// worked
return View(new TestClass { Foo = 1, Bar = "test" });
Run Code Online (Sandbox Code Playgroud)
编辑#1:
根据David Ebbo的说法,您无法将匿名类型传递给动态类型视图,因为匿名类型被编译为internal.由于CSHTML视图被编译为单独的程序集,因此无法访问匿名类型的属性.
编辑#2:
David Ebbo根据这一澄清编辑了他的帖子:
注意(12/22/2011):现在MVC 3直接支持动态,不再需要下面的技术.这篇文章实际上是导致将该功能集成到MVC中的原因!
jos*_*ley 25
我今天遇到了同样的问题,并没有(直接)与传递匿名类型及其固有internal属性的问题有关.
因此,就OPs问题而言,@ Lucas的答案是无关紧要的 - 即使解决方法可行.
在OPs问题中,匿名类型从程序集X中的视图传递到程序集X中的部分,因此David Ebbo概述的匿名类型内部属性的问题并不重要; 为视图,部分和匿名类型编译的类型都包含在同一个程序集中.
至少在我的情况下,我发现它是由于在SAME FOLDER中有另一个视图指定了无法解析的模型类型.视图在运行时被编译,因此在运行时编译视图时失败也意味着编译动态类型失败,而部分只会接收到object.现在并不是很明显,但在OPs的具体例子(和我的)中,这很可能是导致问题的原因.
有趣的是,如果模型类型正确但视图的另一部分未编译,则匿名类型不会以相同方式受到影响.这必须归结为Razor如何分解视图组成部分的动态编译.
一旦纠正了违规视图,重建整个解决方案或清理并重建项目,然后再检查它是否已修复.
为了确保您不会再被这一点抓住,您可以通过将Razor视图添加到您的csproj文件来启用编译时编译:
<PropertyGroup>
<MvcBuildViews>true</MvcBuildViews>
</PropertyGroup>
Run Code Online (Sandbox Code Playgroud)
小智 9
在解决方案的任何位置添加以下类(使用System命名空间,因此可以随时使用而无需添加任何引用) -
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
将模型发送到视图时,将其转换为Expando:
return View(new {x=4, y=6}.ToExpando());
Run Code Online (Sandbox Code Playgroud)
而不是dynamic在局部视图中使用模型类型。
您可以使用@ViewData.Eval("foo")代替来调用匿名对象属性@Model.foo。
然后您可以@Model dynamic从视图中删除。
我最近在 Facebook 社交评论集成的视图之间传递一些属性时遇到了这个问题。示例代码:
Html.RenderPartial(@"Layouts/Partials/_Comments", new {currentUrl = Model.CurrentPage.GetAbsoluteUrl(), commentCount = 5 });
Run Code Online (Sandbox Code Playgroud)
然后在我看来,我只有这个 div:
<div class="fb-comments" data-href="@ViewData.Eval("currentUrl")" data-numposts="@ViewData.Eval("commentCount")" data-width="100%"></div>
Run Code Online (Sandbox Code Playgroud)