刚刚使用Paged List插件将分页添加到我的视图中,我只能将数据带回一页。如果您单击“下一步”或任何其他可用页码,页面将重新提交,您最后会看到一个空白表格。
我逐步完成代码,发现传递回控制器的视图模型对象完全为null。有没有人知道这种方法(即导航到不同的分页列表页面时保留视图模型数据)?
查看模型
public class ZipCodeIndex
{
[DisplayName("Zip Code")]
public string searchZip { get; set; }
public IEnumerable<SelectListItem> StateCodes { get; set; }
[DisplayName("Effective on this date")]
public string searchDate { get; set; }
[DisplayName("State")]
public string searchState { get; set; }
[DisplayName("Territory")]
public string searchTerritory { get; set; }
[DisplayName("New Territory")]
public string newTerritory { get; set; }
[DisplayName("New Description")]
public string newDescription { get; set; }
[DisplayName("New Effective Date")]
public string newEffectiveDate { get; set; }
public IPagedList<ZipCodeTerritory> pagedTerritoryList { get; set; }
public List<ZipCodeTerritory> zipCodeTerritory { get; set; }
public ZipCodeIndex()
{
zipCodeTerritory = new List<ZipCodeTerritory>();
SetStateCodes();
}
//Set state code drop down list
private void SetStateCodes()
{
AgentResources db = new AgentResources();
StateCodes = (from z in db.ZipCodeTerritory
select z.StateCode).Select(x => new SelectListItem
{
Text = x,
Value = x
}).Distinct().ToList();
db.Dispose();
}
}
控制器
public ViewResult Index(int? page, string errorMessage = "", ZipCodeIndex search = null)
{
//set Paged List counter variables
int pageNumber = page ?? 1;
int pageSize = 300;
//If TempData conntains information method call came from another controller action
if (TempData.Count > 0)
{
//Instantiate ZipCodeIndex view model object if it exists
search = (ZipCodeIndex)TempData["ZipCodeIndexData"];
//Clear out previous search results
search.zipCodeTerritory.Clear();
}
//Proceed with search
try
{
//If search criteria is null page is loading for the first time so send blank view
if (String.IsNullOrWhiteSpace(search.searchZip) &&
String.IsNullOrWhiteSpace(search.searchDate) &&
String.IsNullOrWhiteSpace(search.searchState))
{
if (!string.IsNullOrWhiteSpace(search.searchTerritory))
{
ViewBag.ErrorMessage = "State or Zip Code required for search.";
}
//Convert list to IPagedList for pagining on Index
search.pagedTerritoryList = search.zipCodeTerritory.ToPagedList(pageNumber, pageSize);
return View(search);
}
//Determine if necessary search criteria has been sent
if (String.IsNullOrWhiteSpace(search.searchZip) && String.IsNullOrWhiteSpace(search.searchState))
{
ViewBag.ErrorMessage = "Either State or Zip Code Must be Specified";
//Convert list to IPagedList for pagining on Index
search.pagedTerritoryList = search.zipCodeTerritory.ToPagedList(pageNumber, pageSize);
return View(search);
}
DateTime effectiveDate;
//Convert date string to DateTime type
if (String.IsNullOrWhiteSpace(search.searchDate))
{
effectiveDate = DateTime.MinValue;
}
else
{
effectiveDate = Convert.ToDateTime(search.searchDate);
}
//Conduct search by State Code/Date alone
if (String.IsNullOrWhiteSpace(search.searchZip))
{
if (string.IsNullOrWhiteSpace(search.searchTerritory))
{
search.zipCodeTerritory = (from z in db.ZipCodeTerritory
where z.StateCode.Equals(search.searchState) &&
z.EffectiveDate >= effectiveDate
select z).ToList();
}
else
{
search.zipCodeTerritory = (from z in db.ZipCodeTerritory
where z.StateCode.Equals(search.searchState) &&
z.IndDistrnId.Equals(search.searchTerritory) &&
z.EffectiveDate >= effectiveDate
select z).ToList();
}
//Convert list to IPagedList for pagining on Index
search.pagedTerritoryList = search.zipCodeTerritory.ToPagedList(pageNumber, pageSize);
}
return View(search);
}
查看
@model Monet.ViewModel.ZipCodeIndex
@{
ViewBag.Title = "Zip Code Territory Search";
Layout = "~/Views/Shared/_Layout.cshtml";
}
@using PagedList.Mvc;
@using PagedList;
<h2>Zip Code Territory</h2>
@using (Html.BeginForm("Index", "ZipCodeTerritory", FormMethod.Post))
{
<div class="error" id="searchErrors">
@ViewBag.ErrorMessage
</div>
<br/>
<div id="searchBox" class="boxMe">
<div id="zipBox">
@Html.Raw("Zip Code")
@Html.TextAreaFor(model => model.searchZip, new { style = "width: 300px;", placeholder = "Enter up to 35 comma separated zip codes" })
</div>
<div id="dateBox">
@Html.LabelFor(model => model.searchDate)
@Html.TextBoxFor(model => model.searchDate, new { style="width: 80px;"})
<div id="terrBox">
@Html.LabelFor(model => model.searchTerritory)
@Html.TextBoxFor(model => model.searchTerritory, new { style = "width: 30px;padding-left:10px;", maxLength = 3 })
</div>
</div>
<div id="stateBox">
@Html.LabelFor(model => model.searchState)
@Html.DropDownListFor(model => model.searchState, Model.StateCodes, " ")
<button type="submit" id="SearchButton">Search</button>
</div>
</div>
<div style="clear: both;"></div>
}
<br/>
@Html.ActionLink("Create New", "Create")
<br/>
<br/>
<div class="error" id="updateErrors">
@ViewBag.UpdateAction
</div>
@if (Model.zipCodeTerritory.Count > 0)
{
using (Html.BeginForm("Update", "ZipCodeTerritory", FormMethod.Post))
{
@Html.HiddenFor(model => model.searchZip)
@Html.HiddenFor(model => model.searchDate)
@Html.HiddenFor(model => model.searchState)
<div id="cloneBox">
@Html.LabelFor(model => model.newTerritory)
@Html.TextBoxFor(model => model.newTerritory, new { style = "width: 30px;padding-left:10px;", maxLength = 3 })
@Html.LabelFor(model => model.newDescription)
@Html.TextBoxFor(model => model.newDescription, new { style = "width: 250px;padding-left:10px;", maxLength = 30 })
@Html.LabelFor(model => model.newEffectiveDate)
@Html.TextBoxFor(model => model.newEffectiveDate, new { style = "width: 80px;padding-left:10px;" })
</div>
<br/>
<div id="buttonDiv">
<button type="submit" id="CloneButton" name="button" value="clone">Update Selected Items</button>
<button type="submit" id="deleteButton" name="button" value="delete">Delete Selected Items</button>
</div>
<div id="pagingDiv">
@Html.PagedListPager(Model.pagedTerritoryList, page => Url.Action("Index", new { page }))
</div>
<table id="thetable" class="tablesorter" >
<thead>
<th>@Html.CheckBox("SelectAll")</th>
<th>Channel</th>
<th>Territory</th>
<th>Description</th>
<th>State</th>
<th>Zip</th>
<th>Effective</th>
<th>End Date</th>
<th>Last Update By</th>
<th>Last Update Date</th>
<th></th>
</thead>
<tbody id="tableBody">
@for (int i = 0; i < Model.pagedTerritoryList.Count; i++)
{
<tr>
<td>
@Html.CheckBoxFor(model => model.pagedTerritoryList[i].Update)
@Html.HiddenFor(model => model.pagedTerritoryList[i].Update)
</td>
<td>
@Html.DisplayFor(model => model.pagedTerritoryList[i].ChannelCode)
@Html.HiddenFor(model => model.pagedTerritoryList[i].ChannelCode)
</td>
<td>
@Html.DisplayFor(model => model.pagedTerritoryList[i].IndDistrnId)
@Html.HiddenFor(model => model.pagedTerritoryList[i].IndDistrnId)
</td>
<td>
@Html.DisplayFor(model => model.pagedTerritoryList[i].DrmTerrDesc)
@Html.HiddenFor(model => model.pagedTerritoryList[i].DrmTerrDesc)
</td>
<td>
@Html.DisplayFor(model => model.pagedTerritoryList[i].StateCode)
@Html.HiddenFor(model => model.pagedTerritoryList[i].StateCode)
</td>
<td>
@Html.DisplayFor(model => model.pagedTerritoryList[i].ZipCode)
@Html.HiddenFor(model => model.pagedTerritoryList[i].ZipCode)
</td>
<td>
@Html.DisplayFor(model => model.pagedTerritoryList[i].EffectiveDate)
@Html.HiddenFor(model => model.zipCodeTerritory[i].EffectiveDate)
</td>
<td>
@Html.DisplayFor(model => model.pagedTerritoryList[i].EndDate)
@Html.HiddenFor(model => model.pagedTerritoryList[i].EndDate)
</td>
<td>
@Html.DisplayFor(model => model.pagedTerritoryList[i].LastUpdateId)
@Html.HiddenFor(model => model.pagedTerritoryList[i].LastUpdateId)
</td>
<td>
@Html.DisplayFor(model => model.pagedTerritoryList[i].LastUpdateDate)
@Html.HiddenFor(model => model.pagedTerritoryList[i].LastUpdateDate)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id = Model.pagedTerritoryList[i].Id })
@Html.HiddenFor(model => model.pagedTerritoryList[i].Id)
</td>
</tr>
}
</tbody>
</table>
}
}
修改
发现this article并相应地更改了我的@Html.PagedListPager
,但没有运气(仍然传递null
视图模型对象,现在甚至传递null page
参数...)< / p>
<div id="pagingDiv">
@Html.PagedListPager(Model.pagedTerritoryList, page => Url.Action("Index", new RouteValueDictionary()
{
{ "Page", Page},
{ "search", Model }
}), PagedListRenderOptions.PageNumbersOnly)
</div>
答案 0 :(得分:3)
我知道自从这个问题出现以来已经有一年左右了,但我最近找到了一个简单的解决方案来解决这个问题并想分享。最后一个答案是部分正确的,但有一个更简单的方法来实现这一点。
以下是将viewmodel数据从视图传递到控制器并保留数据的示例代码。
让我们说这是你的viewmodel:
public class SearchViewModel
{
public int? Page { get; set; }
public string data1 { get; set; }
public string data2 { get; set; }
public string data3 { get; set; }
public string data4 { get; set; }
public IPagedList SearchResults { get; set; }
public string SearchButton { get; set; }
}
你的简单viewmodel构造方法(没有实际的搜索代码,用作例子):
public ActionResult Index(SearchViewModel model) {
//code using and constructing your returned search results
var pageNumIndex = model.Page ?? 1;
model.SearchR = results.ToPagedList(pageIndex, 25);
return View(model);
}
然后在您看来,@ Html.PagedListPager看起来像:
@Html.PagedListPager(Model.SearchR, Page => Url.Action("Index", new RouteValueDictionary() {
{ "Page", Page },
{ "data1", Model.data1 },
{ "data2", Model.data2 },
{ "data3", Model.data3 },
{ "data4", Model.data4 },
}),
PagedListRenderOptions.PageNumbersOnly)
这种方法将RouteValueDictionary()直接实现到Html.PagedListPager中。
我很难找到使用viewmodel方法的@ Html.PagedListPager解决方案,直到发现RouteValueDictionary()直接方法。
答案 1 :(得分:0)
您修改后的代码只会将参数发送到索引页面:Page,并进行搜索。页面是您想要的页面值,但搜索可能是您的模型类的ToString。
我自己一直在努力解决这个问题,并提出了以下解决方案: 我已将此方法添加到我的模型中,
public RouteValueDictionary GenerateRouteValueDictionary(int page)
{
Page = page;
RouteValueDictionary dic = new RouteValueDictionary
{
{ QueryHelper.Print(() => Page), Page },
{ QueryHelper.Print(() => PreviousSortField), PreviousSortField },
{ QueryHelper.Print(() => SortOrder), SortOrder },
{ QueryHelper.Print(() => SearchString), SearchString },
{ QueryHelper.Print(() => IncludeHidden), IncludeHidden },
{ QueryHelper.Print(() => SearchOperator1), SearchOperator1 },
{ QueryHelper.Print(() => SearchField1), SearchField1 },
{ QueryHelper.Print(() => SearchField1Value), SearchField1Value },
{ QueryHelper.Print(() => WhereOperator), WhereOperator },
{ QueryHelper.Print(() => SearchOperator2), SearchOperator2 },
{ QueryHelper.Print(() => SearchField2), SearchField2 },
{ QueryHelper.Print(() => SearchField2Value), SearchField2Value },
{ QueryHelper.Print(() => FilterByDummyLocations), FilterByDummyLocations },
{ QueryHelper.Print(() => FilterByDummyProfile), FilterByDummyProfile },
{ QueryHelper.Print(() => FilterNoDevice), FilterNoDevice }
};
return dic;
}
从我的cshtml中,我按如下方式生成分页列表:
@Html.PagedListPager(Model.SearchResults, page => Model.GenerateRouteValueDictionary(page)));
(QueryHelper.Print只是一个打印我提供的属性名称的方法...所以我有效地为每个链接重新创建查询字符串。可能不是处理这个问题的最好方法,但它确实有效。
还有另一种方法,首先在模型上设置页码,然后提供模型本身:
@Html.PagedListPager(Model.SearchResults, page => Url.Action(action, Model.SetPage(page)))
使用这种额外的模型方法:
public SearchPbxUsersModel SetPage(int page)
{
Page = page;
SearchPbxUsersModel myModel = this.MemberwiseClone() as SearchPbxUsersModel;
myModel.SearchResults = null;
return myModel;
}
除了克隆之外,您还可以将任何您不喜欢的值置空(并且您甚至必须使某些值无效,例如IPagedList pagedTerritoryList)。
任何一种方法都有一个警告:
如果你还有一个多选控件,你将被卡住,并且必须手动编写你自己的动作链接(真是太痛苦了)。使用第一种方法不会起作用,因为使用multiselect可以多次使用多选控件的查询字符串属性(并且不会使用任何字典),而使用第二种方法,您的容器将保持选中状态值(例如List或IEnumerable)将获得ToString(),因此您的模型将保留一个值,而不是查看您选择的值,而是容器的串串。