动态类型ViewPage
这可能吗?这里就是我想:动态类型ViewPage
public ActionResult Index()
{
dynamic p = new { Name = "Test", Phone = "111-2222" };
return View(p);
}
然后我的观点从System.Web.Mvc.ViewPage<dynamic>
继承并试图打印出Model.Name。
我发现了一个错误:<> f__AnonymousType1.Name'不可访问由于其保护级别
因此,基本上,是什么,我试图做是不可能的?为什么或者为什么不?
更新:这是我的看法
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
<asp:Content ...>
<%=Model.Name%>
<%=Model.Phone%>
</asp:Content>
观构造函数是内置的框架。
匿名类型不能由方法返回;它们仅在其定义方法的范围内有效。
您应该使用您之前定义的模型类并将其传递给您的视图。传递没有定义每个字段的Model类没有任何问题。
更新:
我想我是错了。这应该工作。或许这个问题在视图内。你能发布更多的代码吗?特别是视图及其构造函数。
更新二:
好吧,我错了关于通过一个匿名类型的另一种方法用作动态变量 - 是可以做到的。
但我相信你想要做的事情也是错误的。对你不幸的是,它不会。问题是您正在使用ViewPage<TModel>
,它在内部使用ViewDataDictionary<TModel>
。因为它们需要强类型,所以您将无法使用动态对象。内部结构不仅在内部使用动态,而且在类型失败时指定动态。
需要什么是DynamicViewPage
类和相应的DynamicViewDataDictionary
类接受object
并将其内部存储为动态。然后,您可以使用匿名类型并将其传递给您的视图。
这就是说,你不会获得任何东西。您可以像您所做的那样指定您的视图(即<%=Model.Name%>
),但您不会从强大的打字中受益。没有智能感知,也没有类型安全。正如@Dennis Palmer所建议的那样,你也可以使用无类型的ViewDataDictionary
。
这一直是一个有趣的(但不幸的是,我吸收)思想实验,但我认为,最终,这不会发生。要么声明一个公共类型并将其传递给您的视图,要么使用无类型的字典。
但我可以通过反射访问对象的成员,这就是为什么我认为动态输入可能有效。 – 2009-07-24 17:25:42
你希望从这里使用动态类型获得什么好处?
使用ViewData字典是向您的视图输出添加任意对象/项目的一种非常简单的方法。
您不需要反射即可获取视图中的属性名称。只需使用ViewData.Keys
即可获取名称集合。
编辑:我刚刚了解了一些关于动力学的内容,我想也许您需要创建自己的动态对象类,它继承自DynamicObject。您需要在该课程中使用专用字典,然后覆盖TrySetMember
和TryGetMember
。
编辑另外:我认为强类型ViewModel的一个优点是你可以接受它作为POST Action方法中的一个参数。 MVC框架将处理模型绑定,并且在操作方法中,您只需拥有一个ViewModel类的实例。即使他们工作,我也不认为你拥有动态优势。
编辑结果:嗯,我尝试使用派生自DynamicObject的类,但VS2010在尝试渲染视图时崩溃。我没有得到任何异常,只是一次严重的崩溃,Visual Studio重新启动。这是我提出的代码导致崩溃。
自定义动态类:
public class DynViewModel : DynamicObject
{
private Dictionary<string, object> ViewDataBag;
public DynViewModel()
{
this.ViewDataBag = new Dictionary<string, object>();
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
this.ViewDataBag[binder.Name] = value;
return true;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = this.ViewDataBag[binder.Name];
return true;
}
}
在控制器:
public ActionResult DynamicView()
{
dynamic p = new DynamicViewModel.Models.DynViewModel();
p.Name = "Test";
p.Phone = "111-2222";
return View(p);
}
我的看法是基本相同,是什么在问题中列出:
<p>Name: <%=Model.Name %></p>
<p>Phone: <%=Model.Phone %></p>
我结论:这可能工作,但在VS2010的Beta 1中,我不能弄清楚为什么我的代码会导致Visual Studio崩溃。我将在VS2010 Beta 2中再次尝试它,因为它是学习动态的有趣练习。但是,即使这样做起作用,我仍然没有看到使用ViewData词典的优势。
菲尔·哈克去救援!菲尔哈克的博客文章可能会帮助你。它看起来就是你在找的东西。 Fun With Method Missing and C# 4
这里的实际错误(<>f__AnonymousType1.Name' is inaccessible due to its protection level
)是使用匿名类型的结果。匿名类型隐式地为internal
(至少在C#中),因此它们只能从相同的程序集中正常访问。由于您的视图在运行时编译为单独的程序集,因此它无法访问匿名类型internal
。
解决方案是将混凝土/命名类作为模型传递给您的视图。如果需要,视图本身仍然可以使用dynamic
。
你能发表更多的代码吗?我特别想看到构造函数来查看 – Randolpho 2009-07-24 17:36:14
查看我的最新更新,并链接到Phil Haack的博客文章。 – CoderDennis 2009-08-28 19:51:00