在Razor MVC View中读取隐式返回类型

时间:2011-11-23 22:16:28

标签: asp.net-mvc asp.net-mvc-3 razor

我是razor MVC的新手,我想知道如何读取我在视图中返回的值?

我的代码是这样的:

    public ActionResult Subject(int Category)
    {
        var db = new KnowledgeDBEntities();
        var category = db.categories.Single(c => c.category_id == Category).name;
        var items = from i in db.category_items
                    where i.category_id == Category
                    select new { ID = i.category_id, Name = i.name };
        var entries = from e in db.item_entry
                      where items.Any(item => item.ID == e.category_item_id)
                      select new { ID = e.category_item_id, e.title };
        db.Dispose();


        var model = new { Name = category, Items = items, Entries = entries };
        return View(model);
    }

基本上,我返回一个匿名类型,我必须编写什么代码才能在我的视图中读取匿名类型的值?

如果这是不可能的,那么适当的替代方案是什么?

1 个答案:

答案 0 :(得分:2)

  

基本上,我返回一个匿名类型

不。不会工作。匿名类型由编译器以内部的形式发出,并且由于ASP.NET在运行时将视图编译为单独的程序集,因此无法访问存在于已定义它们的程序集中的那些匿名类型。

在正确设计的ASP.NET MVC应用程序中,您可以使用视图模型。所以你首先定义一些:

public class MyViewModel
{
    public string CategoryName { get; set; }
    public IEnumerable<ItemViewModel> Items { get; set; }
    public IEnumerable<EntryViewModel> Entries { get; set; }
}

public class ItemViewModel
{
    public int ID { get; set; }
    public string Name { get; set; }
}

public class EntryViewModel
{
    public int ID { get; set; }
    public string Title { get; set; }
}

然后您调整控制器操作以将此视图模型传递给视图:

public ActionResult Subject(int Category)
{
    using (var db = new KnowledgeDBEntities())
    {

        var category = db.categories.Single(c => c.category_id == Category).name;
        var items = 
            from i in db.category_items
            where i.category_id == Category
            select new ItemViewModel 
            { 
                ID = i.category_id, 
                Name = i.name 
            };

        var entries = 
            from e in db.item_entry
            where items.Any(item => item.ID == e.category_item_id)
            select new EntryViewModel 
            { 
                ID = e.category_item_id, 
                Title = e.title 
            };

        var model = new MyViewModel 
        { 
            CategoryName = category, 
            Items = items.ToList(),      // be eager
            Entries = entries.ToList()   // be eager
        };
        return View(model);
    }
}

最后,您强烈地将视图输入到您定义的视图模型中:

@model MyViewModel

@Model.Name

<h2>Items:</h2>
@foreach (var item in Model.Items)
{
    <div>@item.Name</div>
}

<h2>Entries:</h2>
@foreach (var entry in Model.Entries)
{
    <div>@entry.Title</div>
}

顺便说一下,为了简化您的域模型和视图模型之间的映射,我建议您查看AutoMapper

哦,因为在视图中编写foreach循环有点难看而且不可重复使用我会建议你使用显示/编辑器模板,它们基本上会让你看起来像这样:

@model MyViewModel

@Model.Name

<h2>Items:</h2>
@Html.DisplayFor(x => x.Items)

<h2>Entries:</h2>
@Html.DisplayFor(x => x.Entries)

然后您将定义相应的显示模板,这些模板将自动为相应集合的每个元素呈现:

~/Views/Shared/DisplayTemplates/ItemViewModel

@model ItemViewModel
<div>@item.Name</div>

~/Views/Shared/DisplayTemplates/EntryViewModel

@model EntryViewModel
<div>@item.Title</div>