2012-01-11 88 views
6

可能重复:
Dynamic Anonymous type in Razor causes RuntimeBinderException动态类型MVC视图

我想在我的MVC应用程序使用动态类型的模型。我有以下代码: 在控制器:

var model = new { Name = "test name", Family = "m" }; 
return this.View(model); 

,并在视图中我有:

@model dynamic 

@if(Model!=null) 
{ 
    <p> @Html.Raw(Model.Name) </p> 
} 

当我运行此,我收到以下错误:

'object' does not contain a definition for 'Name' (System.Exception {Microsoft.CSharp.RuntimeBinder.RuntimeBinderException) 

为什么我得到这个错误? 在调试期间,如果我将光标放在@Model上,我可以看到它有两个名为Name和Family的属性。

+0

你可以因为反射的调试过程中看到'@ Model'属性... – 2012-01-11 13:53:01

+0

谢谢,那么为什么我得到错误?该对象具有该属性并且是动态类型! – mans 2012-01-11 13:54:30

回答

16

你显示的不是动态类型。这是一个匿名类型。有很大的差异。

您不能使用匿名类型作为模型。原因是编译器发出匿名类型内部。这意味着它们只能通过当前的程序集访问。但正如你所知道的Razor视图是由ASP.NET运行时编译的独立程序集,它们无法使用这些匿名类型。

显然,在这种情况下,正确的方法是使用一个视图模型:

public class MyViewModel 
{ 
    public string Name { get; set; } 
    public string Family { get; set; } 
} 

,然后让你的控制器动作通过此视图模型到视图:

var model = new MyViewModel { Name = "test name", Family = "m" }; 
return this.View(model); 

让您的看法可以使用它:

@model MyViewModel 
@if (Model != null) 
{ 
    <p>@Model.Name</p> 
} 

有些人(不是我,我绝不会推荐任何这样的东西)还使用ViewBag而这样一来,他们并不需要一个模型:

ViewBag.Name = "test name"; 
ViewBag.Family = "m"; 
return this.View(); 

,然后在视图:

<p>@ViewBag.Name</p> 
+0

感谢您的解释。我想知道ViewBag是如何实现的?我可以有一个动态模型吗?这篇文章说这是可能的:http://blogs.msdn.com/b/rickandy/archive/2011/01/28/dynamic-v-strongly-typed-views.aspx但我做不到。 – mans 2012-01-11 15:07:45

+0

@ user654019,ViewBag只是​​ViewData词典的一个动态包装。你需要有一些具体的类型作为模型。你可以使用'@model dnyamic',但如果这个模型没有指向特定的类型(不是匿名对象,由于我在我的答案中概述的原因,它不能用于匿名对象),它根本行不通。在你已经链接的博客文章中,他们将dnyamic模型指向他们定义的具体类,比如'Blog','List ',它们都是强类型的。没有一个匿名对象。你可以在ASP.NET MVC中忘记它们。 – 2012-01-11 15:17:38

+0

谢谢,你可以给我一些关于Viewbag如何实现的线索吗?任何文件? – mans 2012-01-11 15:22:43