首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >动态类型的ViewPage

动态类型的ViewPage
EN

Stack Overflow用户
提问于 2009-07-24 17:21:17
回答 4查看 8.6K关注 0票数 12

这个是可能的吗?这是我正在尝试的:

代码语言:javascript
复制
    public ActionResult Index()
    {
        dynamic p = new { Name = "Test", Phone = "111-2222" };
        return View(p);
    }

然后我的视图继承自System.Web.Mvc.ViewPage<dynamic>,并尝试打印出Model.Name。

我收到一个错误:由于其保护级别,'<>f__AnonymousType1.Name‘不可访问

所以基本上,我想要做的事情是不可能的吗?为什么或者为什么不?

更新:这是我的观点

代码语言:javascript
复制
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>

<asp:Content ...>
    <%=Model.Name%>
    <%=Model.Phone%>
</asp:Content>

View构造函数内置于框架中。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-07-24 17:22:51

匿名类型不能由方法返回;它们只在定义匿名类型的方法的作用域内有效。

您应该使用先前定义的Model类,并将其传递给您的View。传递一个没有定义每个字段的Model类并没有什么错。

更新

我想我之前错了。这应该是可行的。也许问题出在视图中。你能发布更多的代码吗?尤其是View及其构造函数。

更新第二个:

好吧,我把匿名类型传递给另一个方法作为动态变量是错误的--这是可以做到的。

但我也错了,我认为你正在尝试做的事情会奏效。不幸的是,对你来说,它不会。问题是您使用的是内部使用ViewDataDictionary<TModel>ViewPage<TModel>。因为它们需要强类型,所以您不能对它们使用动态对象。内部结构只是不在内部使用dynamic,并且指定dynamic作为类型失败。

需要的是一个DynamicViewPage类和相应的DynamicViewDataDictionary类,它们接受object并在内部将其作为动态存储。然后,您可以使用匿名类型并将其传递给视图。

也就是说,你不会得到任何东西。你可以像以前那样指定你的视图(即<%=Model.Name%>),但是你不会从强类型中获益。不会有智能感知,也不会有类型安全。你最好像@Dennis Palmer建议的那样使用非类型化的ViewDataDictionary

这是一个有趣的(不幸的是,对我来说,吸收)思维实验,但我认为,最终,这是不会发生的。要么声明一个公共类型并将其传递给视图,要么使用非类型化字典。

票数 7
EN

Stack Overflow用户

发布于 2009-07-24 17:41:02

您希望从这里使用动态类型中获得什么好处?

使用ViewData字典是将任意对象/项添加到视图输出的一种非常简单的方法。

你不需要反射就能在你的视图中获得属性名。只需使用ViewData.Keys获取名称集合即可。

编辑:我自己刚刚学到了更多关于动力学的知识,我想也许你需要创建你自己的动态对象类,它继承自DynamicObject。您将希望在该类中有一个私有字典,然后覆盖TrySetMemberTryGetMember

编辑旁注:我认为强类型ViewModel的一个优点是你可以在你的POST Action方法中接受它作为一个参数。MVC框架将处理模型绑定,而在action方法中,您只需拥有ViewModel类的一个实例。我不认为即使它们工作,你也不会有这种优势。

编辑结果:嗯,我尝试使用从DynamicObject派生的类,但VS2010在尝试呈现视图时崩溃。我没有得到任何异常,只有硬崩溃和Visual Studio重启。这是我想出的导致崩溃的代码。

自定义动态类:

代码语言:javascript
复制
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;
    }
}

在控制器中:

代码语言:javascript
复制
public ActionResult DynamicView()
{
    dynamic p = new DynamicViewModel.Models.DynViewModel();
    p.Name = "Test";
    p.Phone = "111-2222";

    return View(p);
}

我的看法与问题所列的基本相同:

代码语言:javascript
复制
<p>Name: <%=Model.Name %></p>
<p>Phone: <%=Model.Phone %></p>

我的结论是:这可能行得通,但是在VS2010的Beta1中,我不明白为什么我的代码会导致Visual Studio崩溃。当VS2010 Beta2发布时,我将再次尝试它,因为它是学习动力学的一个有趣的练习。但是,即使这样可以工作,我仍然看不到比使用ViewData字典有任何优势。

Phil Haack拯救!这里有一篇Phil Haack的博客文章,可能会对你有所帮助。看起来这就是你要找的。Fun With Method Missing and C# 4

票数 7
EN

Stack Overflow用户

发布于 2011-03-31 23:35:25

这里的实际错误(<>f__AnonymousType1.Name' is inaccessible due to its protection level)是使用匿名类型的结果。匿名类型是隐式的internal (至少在C#中是这样),因此它们只能从同一个程序集中正常访问。由于视图在运行时被编译成单独的程序集,因此它不能访问internal匿名类型。

解决方案是将具体的/命名的类作为模型传递给视图。如果您愿意,视图本身仍然可以使用dynamic

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1178984

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档