我有一個視圖模型對象,其中包含另一個模型對象類型List
。當用戶在頁面上進行查詢時,如果返回的List
包含超過300條記錄,我們希望使用分頁來減少加載時間(某些搜索結果可能會返回超過14k條記錄)。我們正在使用的分頁插件can be found here.無法創建接口的實例(PagedList)
一旦結果顯示在頁面上,用戶就可以點擊特定結果旁邊的複選框,在輸入文本框中鍵入一些信息,點擊提交,並使用文本框中的信息編輯選定的記錄。
因爲我們需要的,以便使分頁使用一個IPagedList<>
,然而,當你點擊提交(和之前的頁面,甚至打控制器),我們得到以下錯誤:
Cannot create an instance of an interface.
視圖模型
這些是我們用於分頁的兩個列表對象。 zipCodeTerritory
對象保存查詢的結果。 pagedTerritoryList
用於僅顯示用戶所在的特定頁面上的結果。
//Paging List objects
public IPagedList<ZipCodeTerritory> pagedTerritoryList { get; set; }
public List<ZipCodeTerritory> zipCodeTerritory { get; set; }
public IPagedList PagingMetaData { get; set; }
控制器
這是我們的基本搜索。 .ToPagedList
方法用於指定我們要顯示的結果範圍,並將它們放在pagedTerritoryList
對象中。
//set Paged List counter variables
int pageNumber = page ?? 1;
int pageSize = 300;
//Determine if Territory present?
if (string.IsNullOrWhiteSpace(search.searchTerritory))
{
//State Code ONLY search
search.zipCodeTerritory = (from z in db.ZipCodeTerritory
where z.StateCode.Equals(search.searchState)
select z).ToList();
}
else if(string.IsNullOrWhiteSpace(search.searchState))
{
//Territory ONLY search
search.zipCodeTerritory = (from z in db.ZipCodeTerritory
where z.IndDistrnId.Equals(search.searchTerritory)
select z).ToList();
}
else
{
//Territory AND state search
search.zipCodeTerritory = (from z in db.ZipCodeTerritory
where z.IndDistrnId.Equals(search.searchTerritory) &&
z.StateCode.Equals(search.searchState)
select z).ToList();
}
//Convert list to IPagedList for pagining on Index
search.pagedTerritoryList = search.zipCodeTerritory.ToPagedList(pageNumber, pageSize);
//Set Paged List objects
search.PagingMetaData = new StaticPagedList<ZipCodeTerritory>(search.zipCodeTerritory, pageNumber, pageSize,
search.zipCodeTerritory.Count).GetMetaData();
return View(search);
查看
這是一個顯示搜索結果的形式。如果用戶選中該複選框,然後點擊clone
或delete
按鈕,則結果應該被回送到控制器的Update
方法並執行適當的編輯或刪除。用戶想要在編輯中疊加的信息以格式輸入到newTerritory/Description/etc
字段中(在table
之上)。
關於@Html.PagedListPager
我發現我不得不從頁面傳回給索引方法相同的搜索條件,因此RouteValueDictionary
中的參數數量過大。
@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">
<div id="rw1">
@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 id="rw2" style="padding-top: 10px;">
@Html.LabelFor(model => model.newChannelCode)
@Html.DropDownListFor(model => model.newChannelCode, Model.ChannelCodes, " ")
@Html.LabelFor(model => model.newStateCode)
@Html.DropDownListFor(model => model.newStateCode, Model.StateCodes, " ")
</div>
</div>
</div>
<br/>
<div id="buttonDiv">
<button type="submit" id="CloneButton" name="button" value="clone">Apply New Data</button>
<button type="submit" id="deleteButton" name="button" value="delete">Delete Selected Items</button>
</div>
@*Display paging only if necessary*@
if (Model.pagedTerritoryList.Count >= 300)
{
<div id="pagingDiv">
@Html.PagedListPager(new StaticPagedList<Monet.Models.ZipCodeTerritory>(Model.zipCodeTerritory, Model.PagingMetaData) ,
Page => Url.Action("Index", new RouteValueDictionary()
{
{ "Page", Page},
{ "searchZip", Model.searchZip },
{ "searchActiveOnly", Model.searchActiveOnly },
{ "searchDate", Model.searchDate },
{ "searchState", Model.searchState },
{ "searchTerritory", Model.searchTerritory },
{ "searchChannel" , Model.searchChannelCode }
}), PagedListRenderOptions.DefaultPlusFirstAndLast)
</div>
}
<table id="thetable" class="tablesorter" >
<thead>
<th>@Html.CheckBox("SelectAll")</th>
<th>State</th>
<th>Territory</th>
<th>Zip</th>
<th>Description</th>
<th>Effective</th>
<th>End Date</th>
<th>Last Update Date</th>
<th>Channel</th>
<th></th>
</thead>
<tbody id="tableBody">
@for (int i = 0; i < Model.pagedTerritoryList.Count; i++)
{
<tr id="@(Model.lastEditedId == Model.pagedTerritoryList[i].Id ? "lastEdit" : "")">
<td>
@Html.CheckBoxFor(model => model.pagedTerritoryList[i].Update)
@Html.HiddenFor(model => model.pagedTerritoryList[i].Update)
</td>
<td>
@Html.DisplayFor(model => model.pagedTerritoryList[i].StateCode)
@Html.HiddenFor(model => model.pagedTerritoryList[i].StateCode)
</td>
<td>
@Html.DisplayFor(model => model.pagedTerritoryList[i].IndDistrnId)
@Html.HiddenFor(model => model.pagedTerritoryList[i].IndDistrnId)
</td>
<td>
@Html.DisplayFor(model => model.pagedTerritoryList[i].ZipCode)
@Html.HiddenFor(model => model.zipCodeTerritory[i].ZipCode)
</td>
<td>
@Html.DisplayFor(model => model.pagedTerritoryList[i].DrmTerrDesc)
@Html.HiddenFor(model => model.pagedTerritoryList[i].DrmTerrDesc)
</td>
<td>
@Html.DisplayFor(model => model.pagedTerritoryList[i].EffectiveDate)
@Html.HiddenFor(model => model.pagedTerritoryList[i].EffectiveDate)
</td>
<td>
@if (Model.pagedTerritoryList[i].EndDate.Date != DateTime.MaxValue.Date)
{
@Html.DisplayFor(model => model.pagedTerritoryList[i].EndDate)
@Html.HiddenFor(model => model.pagedTerritoryList[i].EndDate)
}
</td>
<td>
@Html.DisplayFor(model => model.pagedTerritoryList[i].LastUpdateDate)
@Html.HiddenFor(model => model.pagedTerritoryList[i].LastUpdateDate)
</td>
<td>
@Html.DisplayFor(model => model.pagedTerritoryList[i].ChannelCode)
@Html.HiddenFor(model => model.pagedTerritoryList[i].ChannelCode)
</td>
@if (ViewBag.SecurityLevel >= 4)
{
<td>
@Html.ActionLink("Edit", "Edit", new
{
id = Model.zipCodeTerritory[i].Id,
searchZip = Model.searchZip,
searchActiveOnly = Model.searchActiveOnly,
searchDate = Model.searchDate,
searchState = Model.searchState,
searchTerritory = Model.searchTerritory,
searchChannelCode = Model.searchChannelCode
})
@Html.HiddenFor(model => model.zipCodeTerritory[i].Id)
</td>
}
</tr>
}
</tbody>
</table>
}
}
編輯
每下面的評論,這裏是形式發佈給該方法的簽名。它包含了獲取網頁上加載本來是ZipCodeIndex
的實例,加上從button
文本,以確定我們是否在做一個clone
或delete
[HttpPost]
public ActionResult Update(ZipCodeIndex updateZip, string button)
{
第二個編輯
試過方法從this question,但仍然收到原始錯誤消息(「無法創建一個接口的實例」)。
如果錯誤的控制器之前,但之後會發生提交,那麼我們可能需要在控制器之前的代碼。可能是控制器和視圖的簽名。 –
好點,剛剛發佈在上面的修改中。謝謝! – NealR
你沒有將頁面傳遞給簽名。 – DarthVader