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

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

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

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

您遇到的问题是,当您的匿名类型存储在ViewData中时,它会被强制转换为对象。 在UI方面,当您获取该对象时,访问其属性的唯一方法是使用reflection。 您不希望在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 Users {get;set;} public static IEnumerable 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> { //snip 

您可能认为让所有这些模型都存在一些浪费,但它更容易理解,并且如果您明智地使用模型,则会使您的UI代码更加纤薄。

此外,模型是一个很好的地方(事实上,应该是你应该在哪里)来放置加载数据和构建模型的逻辑。 想想ActiveRecord。 而且,当你对所有这些进行编码时,要意识到像SubSonic这样的项目会为你创建你的模型而不会有任何麻烦或麻烦。

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

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

希望这是你想要的。

标记

问题不在于它是匿名类型。 问题是它只是一个懒惰评估的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();