【问题标题】:Iterating through anonymous typed data in MVC view在 MVC 视图中遍历匿名类型化数据
【发布时间】:2008-11-12 17:07:08
【问题描述】:

我将匿名类型的结果放入一些视图数据中:

            var projectData = from p in db.Projects
                          orderby p.title
                          select new
                          {
                              Title = p.title,
                              DevURL = p.devURL ?? "N/A",
                              QAURL = p.qaURL ?? "N/A",
                              LiveURL = p.liveURL ?? "N/A",
                              Users = p.GetUsers().MakeUserList()
                          };

        ViewData["ProjectSummary"] = projectData;

如何在前端的MVC视图中遍历这个视图数据说,做一个结果表?

【问题讨论】:

  • 我站在马克和威尔一边。使用实际的模型类来封装模型数据和业务逻辑,使代码更易读,更易于维护,而创建类的成本非常低(无论如何都是域驱动设计的必要条件)。

标签: c# asp.net-mvc anonymous-types


【解决方案1】:

在您的情况下,创建一个模型来保存您的数据比使用匿名类型要简单得多。

您遇到的问题是,当您的匿名类型存储在 ViewData 中时,它会被强制转换为对象。在 UI 方面,当您取出该对象时,访问其属性的唯一方法是使用反射。您不想在您的 UI 中执行此操作。它会非常难看。相反,只需将以下类添加到您的模型中:

public class Project{

public string Title {get;set;}
public string DevUrl {get;set;}
public string QAUrl {get;set;}
public string LiveUrl {get;set;}
public IEnumerable<User> Users {get;set;}

public static IEnumerable<Project> RetrieveAllProjects()
{
  return from p in db.Projects
           orderby p.title
           select new Project
             {
                Title = p.title,
                DevURL = p.devURL ?? "N/A",
                QAURL = p.qaURL ?? "N/A",
                LiveURL = p.liveURL ?? "N/A",
                Users = p.GetUsers().MakeUserList()
             };
}

在您的控制器中执行以下操作:

public ActionResult Index()
{
  return View("Index", Project.RetrieveAllProjects());
}

并在您视图的代码隐藏中,如此强烈地键入它:

//snip
public partial class Index : ViewPage<IEnumerable<Project>>
{
//snip

您可能会认为放置所有这些模型有点浪费,但如果您明智地使用模型,它会更容易理解,并使您的 UI 代码更精简。

此外,模型是放置用于加载数据和构建模型本身的逻辑的好地方(事实上,应该是你做它的地方)。想想 ActiveRecord。而且,当您编写所有这些代码时,请意识到像 SubSonic 这样的项目会为您创建模型,而不会有任何麻烦或大惊小怪。

【讨论】:

  • 感谢您的回复威尔。我明白你的意思,我有点希望我能够以某种方式在我的前端代码中使用匿名类型,但我想它不会太干净。我讨厌制作显示类:)
  • 您的显示类应该封装这些类的加载逻辑。您不应该在控制器中加载数据;这不在他们的工作描述中。所以你不必将它们视为垃圾......
【解决方案2】:

没有尝试过使用匿名类型,但这是我通过将List&lt;T&gt; 对象传递给ViewData 来实现的方法

<% foreach (Project p in (IEnumerable<Project>)ViewData["ProjectSummary"]) { %>
     <%= Html.Encode(p.Title) %>
<% } %>

希望这就是您想要的。

标记

【讨论】:

    【解决方案3】:

    问题不在于它是匿名类型。问题是它只是一个惰性求值的 IQueryable 对象,还没有被求值。

    我无法回答 ASP.NET MVC,但在非常相似的 Monorail 中,您必须将其从迭代器转换为实际集合:

            var projectData = (from p in db.Projects
                          orderby p.title
                          select new
                          {
                              Title = p.title,
                              DevURL = p.devURL ?? "N/A",
                              QAURL = p.qaURL ?? "N/A",
                              LiveURL = p.liveURL ?? "N/A",
                              Users = p.GetUsers().MakeUserList()
                          }).ToList();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-11
      相关资源
      最近更新 更多