ASP.Net MVC Stongly Typed Views

时间:2009-06-04 07:55:18

标签: asp.net-mvc

我在正在处理的ASP.Net MVC项目中创建了一个强大的类型视图,该视图只是一个索引页面,列出了网格中SQL表的内容。

我现在想添加过滤此列表的功能。我试图通过在视图中创建一个包含可以过滤的值的下拉列表来完成此操作。这个想法是,当用户提交该表单时,它会触发控制器Post索引方法,该方法将从传递给方法的FormCollection中获取所选值的下拉列表。

例如,我的2个索引方法看起来像这样

 public ActionResult Index()
    {
        DevAdminEntities db = new DevAdminEntities();
        ViewData["StatusDropDown"] = new SelectList(db.TaskStatuses, "TaskStatusId", "StatusName");
        return View(db.Tasks);
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Index(FormCollection formValues)
    {
        DevAdminEntities db = new DevAdminEntities();
        ViewData["StatusDropDown"] = new SelectList(db.TaskStatuses, "TaskStatusId", "StatusName");
        return View(from t in db.Tasks where t.Projects.ProjectId == int.Parse(Request.Form["StatusDropDown"]) new { t, t.Projects});
    }

当页面以未经过滤的形式加载时,页面显示正常但是当我单击提交按钮以应用过滤器时,我收到以下错误

传入字典的模型项的类型为'System.Data.Objects.ObjectQuery 1[System.Int32]' but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable 1 [DevAdmin.Models.Tasks]'。

视图如下所示

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<DevAdmin.Models.Tasks>>" %>    
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
    <title>Index</title>
</asp:Content>    
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">    
    <h2>Tasks</h2>        
    <%= Html.ValidationSummary() %>
    <% using (Html.BeginForm()) {%>
        <fieldset>
            <legend>Filters</legend>           
            <p>
               <%= Html.DropDownList("StatusDropDown") %>
                <input type="submit" value="Filter" />
            </p>                    
        </fieldset>
    <% } %>            
    <table>
        <tr>
            <th></th>
            <th>
                TaskId
            </th>
            <th>
                Subject
            </th>
            <th>
                Description
            </th>
        </tr>    
    <% foreach (var item in Model) { %>        
        <tr>
            <td>
                <%= Html.ActionLink("Edit", "Edit", new {  id=item.TaskId }) %> |
                <%= Html.ActionLink("Details", "Details", new { id = item.TaskId })%>
            </td>
            <td>
                <%= Html.Encode(item.TaskId) %>
            </td>
            <td>
                <%= Html.Encode(item.Subject) %>
            </td>
            <td>
                <%= Html.Encode(item.Description) %>
            </td>
        </tr>        
    <% } %>    
    </table>    
    <p>
        <%= Html.ActionLink("Create New", "Create") %>
    </p>    
</asp:Content>

知道我做错了吗?

4 个答案:

答案 0 :(得分:5)

嗯,有点在错误消息中说你做错了什么。

该视图需要将IEnumerable1<Tasks>作为模型传递给它,但您传递的是new { t, t.Projects}

另外,在你的代码中放一些喘息的空间..

替换

return View(*hard to read code here*);

int currentStatus = int.Parse(Request.Form["StatusDropDown"];
var tasks = db.Tasks.Where(t => t.ProjectId.Equals(currentStatus));
return View("Index", tasks.AsEnumerable());

答案 1 :(得分:1)

1)return View(db.Tasks);返回IEnumerable

2)return View(from t in db.Tasks where t.Projects.ProjectId == int.Parse(Request.Form["StatusDropDown"]) new { t, t.Projects});返回IQueryable。

所以你必须选择: 将1)更改为return View(db.Tasks).AsQueryable()并在您的视图中将类型更改为IQueryable。

或将2)更改为return View(from t in db.Tasks where t.Projects.ProjectId == int.Parse(Request.Form["StatusDropDown"]) new { t, t.Projects}).AsEnumerable();

IEnumerable是Linq to Object IQueryable适用于Linq to SQL和其他权限。

答案 2 :(得分:0)

ActionResult的签名需要

public ActionResult Index(FormCollection formValues)

FormCollection I是IEnumerable类型。但是,在您的视图中,您将从下拉列表中回发所选索引,即Int32

<%= Html.DropDownList("StatusDropDown") %>
<input type="submit" value="Filter" />

您应该更改ActionResult签名以接受int

答案 3 :(得分:0)

表单是发布附加到下拉列表的值,将方法参数从FormCollection更改为int []