作者:gshackles 翻译:Deboy Wang
出处:http://www.gregshackles.com/2010/09/anonymous-view-models-in-asp-net-mvc-using-dynamics/
声明:版权属原作者所有,转载请注明出处!
C# 4.0中的新出现的dynamic关键字允许你做到很多以前很难实现的事情,但是dynamic也很容易让你忘记C#本身还是一个强类型的编程语言,所以,在使用中就会产生误区。最近我发现我自己想要创建测试用的View页面,后面有一个简单的控制器相对应。因为是临时使用,所以我使用了一个复杂匿名对象作为Model,并且使用dynamic视图来显示它。结果我错了….
下面我们先看一段简单的示例来说明问题。下面给出控制器中的操作方法,传递一个匿名类型到前台的View模型中:
public ActionResult UsingDynamic()
{
return View(new
{
TestString = "This is a test string"
});
}
下面我们来确认一下,这个匿名类型对象,正确的传递到了View中。
<%: Model %>
{ TestString = This is a test string }
<%: Model.TestString %>
这时候ASP.NET抛出一个异常:
“object”不包含“TestString”的定义。
怎么会这样呢?我们清楚地看到传递过来的对象的确包含“TestString”属性和值,当我们打印object的时候抱着个错误。其根本原因是:
匿名类型默认访问修饰符为internal这意味着他们只可以从其定义的程序集中被访问。一旦你超越了程序集的边界,将会被当做普通的object对象被解析,因此不具备TestString的属性。
既然如此,我们怎么能够按照我们预想的那样,可以直接在View中调用到TestString以使用其值呢?使用POCO
我知道按照下面的写法一定可以解决问题。public class PocoViewModel
{
public string TestString { get; set; }
}
public ActionResult UsingPoco()
{
return View(new PocoViewModel()
{
TestString = "This is a test string"
});
}
public ActionResult UsingExpando()
{
dynamic viewModel = new ExpandoObject();
viewModel.TestString = "This is a test string";
return View(viewModel);
}