在某些视图数据中我放了一个匿名类型的结果:
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视图中迭代这个视图数据来说出一个结果表?
答案 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();