在MVC视图中迭代匿名类型数据

时间:2008-11-12 17:07:08

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

在某些视图数据中我放了一个匿名类型的结果:

            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视图中迭代这个视图数据来说出一个结果表?

3 个答案:

答案 0 :(得分:5)

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

您遇到的问题是,当您的匿名类型存储在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这样的项目会为你创建模型而不会有任何麻烦或麻烦。

答案 1 :(得分:1)

没有使用匿名类型尝试此操作,但这是通过将List<T>对象传递给ViewData

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

希望这就是你要找的东西。

马克

答案 2 :(得分:0)

问题不在于它是匿名类型。问题是它只是一个懒惰评估的IQueryable&lt;&gt;对象,尚未评估。

我无法回答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();