2

List別のモデル オブジェクト タイプを含むビュー モデル オブジェクトがあります。ユーザーがページでクエリを実行したときに、List返されたレコードに 300 を超えるレコードが含まれている場合、読み込み時間を短縮するためにページングを使用したいと考えています (一部の検索結果では 14,000 レコードを超えるレコードが返される場合があります)。使用しているページング プラグインは、ここにあります。

結果がページに表示されると、ユーザーは特定の結果の横にあるチェック ボックスをクリックし、入力テキスト ボックスに情報を入力して [送信] をクリックし、選択したレコードをテキストの情報で編集することができます。箱。

ただし、ページングを有効にするためにを使用する必要があったIPagedList<>ため、submit を押すと (ページがコントローラーに到達する前に)、次のエラーが発生します。

                 Cannot create an instance of an interface.

モデルを見る

これらは、ページングに使用する 2 つのリスト オブジェクトです。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、ページから同じ検索基準を index メソッドに戻さなければならないことがわかりました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これには、最初にページにロードされるのインスタンスとbuttoncloneまたはdelete

    [HttpPost]
    public ActionResult Update(ZipCodeIndex updateZip, string button)
    {

2 回目の編集

この質問の方法を試しましたが、元のエラー メッセージ (「インターフェイスのインスタンスを作成できません」) が引き続き表示されます。

4

2 に答える 2

0

プロパティとしてインターフェイスを持つモデルでは、使用する実装を決定するために ModelBinder を作成する必要があることがわかりました。

ASP.Net MVC カスタム モデル バインディングの説明

基本的に、バインダーはモデルを解析し、実装する IPagedList<> のタイプを決定します。

于 2013-10-14T19:23:25.283 に答える