ASP.NET使用非索引将列表从表头ActionLink中的IEnumerable @model传递回控制器 [英] ASP.NET passing List back to controller from IEnumerable @model inside Table header ActionLink with non-indexing
问题描述
我一直在审查将IEnumerable类型的View的@model信息返回给控制器的可能方法,因此,如果我对数据库中的查询进行排序/过滤,则可以优化每次迭代的返回值而无需重新启动将返回新的完整列表.所有方法都表明您需要基于model [index]进行回发,如果您位于for循环中,则可以使用该方法.但是我正在从表的标头部分中的@ HTML.ActionLink发回集合,因此没有可用的索引.
我的WebAPI设置基于此,其中显示了如何进行排序和过滤.我试图使其更加复杂,因为在基于原始数据库查询过滤列表之后,我将能够(从表的标题列的clickable-actionLink中)对过滤后的列表进行排序;从目前的位置来看,它只是从一个完整的完整列表中排序.
我想到的唯一方法是(通过POST)将customClass的更新列表传递回控制器.
@ Html.ActionLink(名称",索引",新的{orderBy = ViewBag.sortByName, companyListIds =模型. })
一个更好的选择(基于Tacud的评论),它需要一个较小的POST URL,方法是返回id属性的列表,然后仅将其应用于查询.但是它仍然是列表,并且仍然需要发回而没有来自和ActionLink的索引.这将有助于保持追踪,并让我继续深入研究越来越小的清单.
下面是模型类的一部分,控制器的索引Action和索引视图. 模型名称空间:
public class Company
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
}
控制器命名空间:
public async Task<IActionResult> Index(ICollection<int> prev, string orderBy , string searchCategory ="", string searchString = "")
{
List<string> Categories = new List<string>() { "Name", "City", "State", "Zip", "Contact Person" };
ViewBag.searchCategory = new SelectList(Categories);
ViewBag.sortByName = orderBy == null ? "name" : orderBy == "name" ? "namedesc" : "name";
ViewBag.sortByCity = orderBy == "city" ? "citydesc" : "city";
ViewBag.sortByState = orderBy == "state" ? "statedesc" : "state";
ViewBag.companyIndex = companyList.Count==0 ? await _context.Company.ToListAsync() : companyList ;
List<Company> resultSet = new List<Company>(ViewBag.companyIndex);
if (!String.IsNullOrEmpty(searchCategory) && !String.IsNullOrEmpty(searchString))
{
switch (searchCategory)
{
.....
}
}
switch (orderBy)
{
....
}
return View(resultSet);
}
查看名称空间:
@model IEnumerable<Laier_It.Models.Company> <p> @using (Html.BeginForm() { <p> Search By: @Html.DropDownList("SearchCategory", "") Search For: @Html.TextBox("SearchString") <input type="submit" value="Filter" /> </p> } <table class="table "> <thead> <tr> <th> @Html.ActionLink("Name", "Index", new { orderBy = ViewBag.sortByName, companyList = Model }) </th> <th> @Html.DisplayNameFor(model => model.Address) </th> <th> @Html.ActionLink("City", "Index", new { orderBy = ViewBag.sortByCity, companyList = Model }) </th> <th> @Html.ActionLink("State", "Index", new { orderBy = ViewBag.sortByState, companyList = Model }) </th> </tr> </thead> <tbody> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.Name) </td> <td> @Html.DisplayFor(modelItem => item.Address) </td> <td> @Html.DisplayFor(modelItem => item.City) </td> <td> @Html.DisplayFor(modelItem => item.State) </td> </tr> } </tbody> </table>
首先要获取要发送回我使用的@Model.Select(x => x.Id)
内WebAPI视图页面中显示的当前格式控制器的ID列表. >
仅此更改了我的控制器索引方法
var resultSet = prev.Count == 0 ? await _context.Company.ToListAsync() :
await _context.Company.Where(x => prev.Contains(x.Id)).ToListAsync();
我的视图如下:
@model IEnumerable<Laier_It.Models.Company>
@using (Html.BeginForm() )
{
<p>
Search By: @Html.DropDownList("SearchCategory", "")
Search For: @Html.TextBox("SearchString")
<input type="submit" value="Filter" />
</p>
}
<table class="table ">
<thead>
<tr>
<th>
@Html.ActionLink("Name", "Index", new { orderBy = ViewBag.sortByName, prev = @Model.Select(x => x.Id) } )
</th>
<th>
@Html.DisplayNameFor(model => model.Address)
</th>
<th>
@Html.ActionLink("City", "Index", new { orderBy = ViewBag.sortByCity, prev = @Model.Select(x => x.Id) } )
</th>
<th>
@Html.ActionLink("State", "Index", new { orderBy = ViewBag.sortByState, prev = @Model.Select(x => x.Id) } )
</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Address)
</td>
<td>
@Html.DisplayFor(modelItem => item.City)
</td>
<td>
@Html.DisplayFor(modelItem => item.State)
</td>
</tr>
}
</tbody>
</table>
I have been reviewing possible ways to return a View's @model information which is of type IEnumerable back to the controller, so that if I sort/filter on a query from database, I can refine the return each iteration without restarting with a fresh full list being returned. All the ways show you need to POST back based on model[index] which works if you are inside a for loop. But I am working with sending the collection back from an @HTML.ActionLink within a table's header section, so there is no possible indexing available.
My WebAPI setup is based on this where they show how to sort and filter. I am trying to make it a little more complex in that after I filter a list based on my original DB query, I will then be able to sort (from a clickable-actionLink on a table's header column) from that filtered list; where as currently it would just sort from a fresh complete list.
The only way I can think of to do this is pass back (by a POST) to the controller the updated list of the customClass.
@Html.ActionLink("Name", "Index", new { orderBy = ViewBag.sortByName, companyListIds = Model.???? })
A better option (based on comments from Tacud) which would require a smaller POST URL would be by returning a list of the id properties only which can then be applied to a query. But its still a list and still needs to be sent back without an index from and ActionLink. This will help keep track and allow me to continue drilling down to a smaller and smaller list.
Below is parts of my model class, the index Action from the controller, and the index view. Model namespace:
public class Company
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
}
Controller Namespace:
public async Task<IActionResult> Index(ICollection<int> prev, string orderBy , string searchCategory ="", string searchString = "")
{
List<string> Categories = new List<string>() { "Name", "City", "State", "Zip", "Contact Person" };
ViewBag.searchCategory = new SelectList(Categories);
ViewBag.sortByName = orderBy == null ? "name" : orderBy == "name" ? "namedesc" : "name";
ViewBag.sortByCity = orderBy == "city" ? "citydesc" : "city";
ViewBag.sortByState = orderBy == "state" ? "statedesc" : "state";
ViewBag.companyIndex = companyList.Count==0 ? await _context.Company.ToListAsync() : companyList ;
List<Company> resultSet = new List<Company>(ViewBag.companyIndex);
if (!String.IsNullOrEmpty(searchCategory) && !String.IsNullOrEmpty(searchString))
{
switch (searchCategory)
{
.....
}
}
switch (orderBy)
{
....
}
return View(resultSet);
}
View namespace:
@model IEnumerable<Laier_It.Models.Company> <p> @using (Html.BeginForm() { <p> Search By: @Html.DropDownList("SearchCategory", "") Search For: @Html.TextBox("SearchString") <input type="submit" value="Filter" /> </p> } <table class="table "> <thead> <tr> <th> @Html.ActionLink("Name", "Index", new { orderBy = ViewBag.sortByName, companyList = Model }) </th> <th> @Html.DisplayNameFor(model => model.Address) </th> <th> @Html.ActionLink("City", "Index", new { orderBy = ViewBag.sortByCity, companyList = Model }) </th> <th> @Html.ActionLink("State", "Index", new { orderBy = ViewBag.sortByState, companyList = Model }) </th> </tr> </thead> <tbody> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.Name) </td> <td> @Html.DisplayFor(modelItem => item.Address) </td> <td> @Html.DisplayFor(modelItem => item.City) </td> <td> @Html.DisplayFor(modelItem => item.State) </td> </tr> } </tbody> </table>
To first obtain the list of Id's that I want to post back to the controller of the current rendition showing within the WebAPI view page I used @Model.Select(x => x.Id)
My controller index method was only changed by this
var resultSet = prev.Count == 0 ? await _context.Company.ToListAsync() :
await _context.Company.Where(x => prev.Contains(x.Id)).ToListAsync();
And my View looks like this:
@model IEnumerable<Laier_It.Models.Company>
@using (Html.BeginForm() )
{
<p>
Search By: @Html.DropDownList("SearchCategory", "")
Search For: @Html.TextBox("SearchString")
<input type="submit" value="Filter" />
</p>
}
<table class="table ">
<thead>
<tr>
<th>
@Html.ActionLink("Name", "Index", new { orderBy = ViewBag.sortByName, prev = @Model.Select(x => x.Id) } )
</th>
<th>
@Html.DisplayNameFor(model => model.Address)
</th>
<th>
@Html.ActionLink("City", "Index", new { orderBy = ViewBag.sortByCity, prev = @Model.Select(x => x.Id) } )
</th>
<th>
@Html.ActionLink("State", "Index", new { orderBy = ViewBag.sortByState, prev = @Model.Select(x => x.Id) } )
</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Address)
</td>
<td>
@Html.DisplayFor(modelItem => item.City)
</td>
<td>
@Html.DisplayFor(modelItem => item.State)
</td>
</tr>
}
</tbody>
</table>
这篇关于ASP.NET使用非索引将列表从表头ActionLink中的IEnumerable @model传递回控制器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!