2009-06-04 146 views
1

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

我现在要添加功能来过滤此列表。我试图通过在视图中创建一个包含您可以过滤的值的下拉列表来创建表单。这个想法是,当用户提交表单时,它会触发控制器的Post index方法,该方法将从传递给方法的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> 

任何想法我做错了什么?

+1

还有一个提示:通常最好将过滤器设置为“GET”方法而不是“POST”。这样人们可以为他们的过滤器添加书签,并且可以创建指向特定过滤器的链接过滤器是一种不会改变资源中的任何内容的操作,因此它应该是“GET”。 – Gidon 2009-06-04 08:08:52

回答

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()); 
0

Action的签名结果期望

public ActionResult Index(FormCollection formValues) 

其中FormCollection I是IEnumerable类型。然而,在你看来,你是从降回发所选择的指数下降,这是一个Int32

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

你应该改变的ActionResult签名接受int

0

形式发布附连到下拉的值,则该方法从参数变化的FormCollection为int []

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到对象。
IQueryable适用于Linq to SQL和其他实体。