Asp.net mvc ASP.NETMVC类型化视图

Asp.net mvc ASP.NETMVC类型化视图,asp.net-mvc,Asp.net Mvc,我在一个ASP.NETMVC项目中创建了一个类型化视图,该视图只是一个索引页,列出了网格中SQL表的内容 现在我想添加过滤此列表的功能。我试图通过在视图中创建一个表单来实现这一点,该表单具有一个下拉列表,其中包含可以筛选的值。其思想是,当用户提交表单时,它会触发控制器Post index方法,该方法将从传递到该方法的FormCollection中的下拉列表中获取所选值 例如,我的两个索引方法如下所示 public ActionResult Index() { DevAd

我在一个ASP.NETMVC项目中创建了一个类型化视图,该视图只是一个索引页,列出了网格中SQL表的内容

现在我想添加过滤此列表的功能。我试图通过在视图中创建一个表单来实现这一点,该表单具有一个下拉列表,其中包含可以筛选的值。其思想是,当用户提交表单时,它会触发控制器Post index方法,该方法将从传递到该方法的FormCollection中的下拉列表中获取所选值

例如,我的两个索引方法如下所示

 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});
    }
<%@ 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>
页面以未过滤的形式加载时显示良好,但当我单击submit按钮应用过滤器时,出现以下错误

“传递到字典中的模型项的类型为'System.Data.Objects.ObjectQuery
1[System.Int32]”,但此字典需要'System.Collections.Generic.IEnumerable
1[DevAdmin.Models.Tasks]'类型的模型项。”

景色是这样的

 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});
    }
<%@ 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>

指数
任务
过滤器

塔西德 主题 描述 |


知道我做错了什么吗?

嗯,它在错误信息中有点说你做错了什么

视图需要一个
IEnumerable1
作为模型传递给它,但您正在传递一个
new{t,t.Projects}

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

替换

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


嗯,它有点在错误信息中说明了你做错了什么

视图需要一个
IEnumerable1
作为模型传递给它,但您正在传递一个
new{t,t.Projects}

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

替换

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


ActionResult的签名应为

public ActionResult Index(FormCollection formValues)
其中FormCollection是IEnumerable类型。但是,在您的视图中,您正在从下拉列表中发回所选索引,该下拉列表是
Int32

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


您应该更改ActionResult签名,以接受ActionResult的签名

public ActionResult Index(FormCollection formValues)
其中FormCollection是IEnumerable类型。但是,在您的视图中,您正在从下拉列表中发回所选索引,该下拉列表是
Int32

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


您应该更改ActionResult签名以接受
int
表单正在发布附加到下拉列表的值,将方法参数从FormCollection更改为int[]

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

返回视图(db.Tasks);返回IEnumerable

2)
返回视图(从db.Tasks中的t开始,其中t.Projects.ProjectId==int.Parse(Request.Form[“StatusDropDown]”)new{t,t.Projects})返回IQueryable

因此,您必须选择: 将1)更改为
返回视图(db.Tasks).AsQueryable()
并在视图中将类型更改为IQueryable

或者将2)更改为
返回视图(从db.Tasks中的t开始,其中t.Projects.ProjectId==int.Parse(Request.Form[“StatusDropDown]”),新建{t,t.Projects})

IEnumerable用于Linq对象。
IQueryable用于Linq到SQL和其他实体。

1)
返回视图(db.Tasks)
2) 
返回视图(从db.Tasks中的t开始,其中t.Projects.ProjectId==int.Parse(Request.Form[“StatusDropDown]”)new{t,t.Projects})返回IQueryable

因此,您必须选择: 将1)更改为
返回视图(db.Tasks).AsQueryable()
并在视图中将类型更改为IQueryable

或者将2)更改为
返回视图(从db.Tasks中的t开始,其中t.Projects.ProjectId==int.Parse(Request.Form[“StatusDropDown]”),新建{t,t.Projects})

IEnumerable用于Linq对象。

IQueryable适用于Linq to SQL和其他实体。

还有一个提示:通常最好将过滤器作为“GET”方法,而不是“POST”。通过这种方式,人们可以将他们的过滤器添加到书签中,您还可以创建指向特定过滤器的链接。Filter是一个不会改变资源中任何内容的操作,所以它应该是“GET”。听起来很有趣,有没有关于我将如何做的提示?我还会使用视图中的表单提交过滤器吗?如果没有定义过滤器,页面是否还能工作?谢谢您应该在controlleraction中检查是否定义了筛选器。(检查null)正如Thomas所说,您将只有一个Index()方法,它具有FormsCollection参数。如果该参数为空,则不进行筛选,否则将开始筛选。还有一个提示:通常最好将筛选作为“GET”方法,而不是“POST”。通过这种方式,人们可以将他们的过滤器添加到书签中,您还可以创建指向特定过滤器的链接。Filter是一个不会改变资源中任何内容的操作,所以它应该是“GET”。听起来很有趣,有没有关于我将如何做的提示?我还会使用视图中的表单提交过滤器吗?如果没有定义过滤器,页面是否还能工作?谢谢您应该在controlleraction中检查是否定义了筛选器。(检查null)正如Thomas所说,您将只有一个Index()方法,它具有FormsCollection参数。如果该参数为空,则不进行筛选,否则将开始筛选。