Mvc 5 pagination using view model

2019-09-22 04:37发布

问题:

Hi i am newbie to Mvc i have a json service which returns a list of walletstatementlogs based on fromdate and todate. I have a controller TopUpReqLogController every time when i hit the action index of the controller it will go to service and fetch the data and returns to view as Ipagedlist and genrates pagelinks. How do i prevent servicecall everytime in TopUpReqLogController index action i just want to load service data once and pass it to index and display data in pages using int ? page please suggest

 public class WalletTopUpRequest
    {

        public string SlNo { get; set; }
        public string Sequence { get; set; }
        public string Merchant { get; set; }
        public string CustomerCode { get; set; }
        public string CustomerName { get; set; }
        public string BankName { get; set; }
        public string TransactionDate { get; set; }
        public string Reference { get; set; }
        public string Amount { get; set; }
        public string ApprovalStatus { get; set; }
        public string ApproveUser { get; set; }
        public string ApprovalDate { get; set; }
        public string RemarKs { get; set; }
    }


public ViewResult Index(int? page)
        {
            int pageSize = 3;
            int pageNumber = (page ?? 1);
            List<WalletTopUpRequest> wallettoprq = new List<WalletTopUpRequest>();
            if (page == null)
            {
                AgentBusiness business = new AgentBusiness();
                var result = business.Topuprequestlog("99910011010", "99810001110", "jBurFDoD1UpNPzWd/BlK4hVpV8GF+0eQT+AfNxEHHDKMB25AHf6CVA==", "25052017000000", "01062017000000");
                wallettoprq = result.wallettopuprequest.ToList();
                var viewmodel = wallettoprq.ToPagedList(pageNumber, pageSize);
                return View(viewmodel);
            }

            return View(wallettoprq.ToPagedList(pageNumber, pageSize));  
        }

@using PagedList;
@using PagedList.Mvc;
@model  IPagedList<HaalMeer.MVC.Client.Models.WalletTopUpRequest>

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<html>
<head>
</head>
<body>
   <div id="page-wrapper">
        <div class="page-title-container">
            @*<div class="container-fluid">*@
                <div class="page-title pull-left">
                    <h2 class="entry-title">Topup Request Log</h2>
                </div>
                <ul class="breadcrumbs pull-right">
                    <li><a href="#">Home</a></li>
                    <li class="active">Topup Request Log</li>
                </ul>
            </div>
        </div>
        <section id="content" class="gray-area">
            <div class="container">
                <div class="row">
                    <div class="col-md-3">
                    </div>
                    @using (Html.BeginForm("Index", "TopUpReqLog", FormMethod.Get))
                    {
                    <div class="col-md-3">
                        <div class="form-group">
                            <label>From Date</label>
                            <div class="datepicker-wrap blue">
                                @*<input type="text" name="date_from" class="input-text full-width" placeholder="mm/dd/yy" style="background-color: #fff" />*@
                                @Html.TextBox("Fromdate", ViewBag.fromdate as string, new { @class = "input-text full-width", @placeholder = "mm/dd/yyy",@style = "background-color: #fff" }) <br />

                            </div>
                        </div>
                    </div>

                    <div class="col-md-3">
                        <div class="form-group">
                            <label>To Date</label>
                            <div class="datepicker-wrap blue">
                                @*<input type="text" name="date_from" class="input-text full-width" placeholder="mm/dd/yy" style="background-color: #fff" />*@
                                @Html.TextBox("Todate", ViewBag.todate as string, new { @class = "input-text full-width", @placeholder = "mm/dd/yyy", @style = "background-color: #fff" }) <br />

                            </div>
                        </div>
                        <button type="submit">Submit</button>
                    </div>
                    }

                    <div class="col-md-3">
                    </div>

                </div>
                <div class="row">
                    <div class="col-md-12 col-sm-12">
                        <div class="table-responsive">

                            <table class="table">
                                <tr class="info" style="text-align: center; font-weight: bold; color: #000">
                                    <td class="col-md-1">Sl</td>
                                    <td class="col-md-2">Date</td>
                                    <td class="col-md-1">Bank Ref.</td>
                                    <td class="col-md-1">Bank Name</td>
                                    <td class="col-md-2">Remarks</td>
                                    <td class="col-md-1">Amount</td>
                                    <td class="col-md-1">Status</td>
                                    <td class="col-md-2">Action Date</td>
                                </tr> 


                                        @foreach (var item in Model)
                                        {
                                        <tr>
                                            <td class="hmcenter">@Html.DisplayFor(modelItem => item.SlNo)</td>
                                            <td class="hmcenter">@Html.DisplayFor(modelItem => item.TransactionDate)</td>
                                            <td class="hmcenter">@Html.DisplayFor(modelItem => item.Reference)</td>
                                            <td class="hmcenter">@Html.DisplayFor(modelItem => item.BankName)</td>
                                            <td class="hmleft">@Html.DisplayFor(modelItem => item.RemarKs)</td>
                                            <td class="hmright">@Html.DisplayFor(modelItem => item.Amount) </td>
                                            <td class="hmcenter">@Html.DisplayFor(modelItem => item.ApprovalStatus)</td>
                                            <td class="hmcenter">@Html.DisplayFor(modelItem => item.ApprovalDate)</td>
                                        </tr>

                                         }



                            </table>
                            <br/>

                            Page @(Model.PageCount<Model.PageNumber? 0 : Model.PageNumber) of @Model.PageCount

                            @Html.PagedListPager(Model, page => Url.Action("Index",new { page
                                            }))


                   @*<div class="form-group">
                    <ul class="pagination">
                        <li><a href="#">1</a></li>
                        <li class="active"><a href="#">2</a></li>
                        <li><a href="#">3</a></li>
                        <li><a href="#">4</a></li>
                        <li><a href="#">5</a></li>
                        <li><a href="#">3</a></li>
                        <li><a href="#">4</a></li>
                        <li><a href="#">5</a></li>
                    </ul>
                </div>*@

                        </div>
                    </div>



                </div>

           </div>
        </section>

回答1:

So, from what I understand you want just make it work only on client side. If your model is not empty this code should work. If you want to load data as one result and make pagination on client side, then IPageList is not what you are looking for. Because, it is used only on the server side, and always returns ONE page of data to brake large results. You also can try to pass list of data to the view and turn it to IPageList result in the view and display each page in tab, but is not a good practice. I would use datatables in this situation to make pagination only on the client side using regular data list: https://datatables.net/. Hint to improve current code:
Controller:

    public ViewResult Index(int? page = 1)
    {
      AgentBusiness business = new AgentBusiness();
      var result = business.Topuprequestlog("99910011010", "99810001110", "jBurFDoD1UpNPzWd/BlK4hVpV8GF+0eQT+AfNxEHHDKMB25AHf6CVA==", "25052017000000", "01062017000000");                 
      return View(result.wallettopuprequest.ToPagedList(pageNumber, 3)); 
    }

View:

@Html.PagedListPager(Model, page => Url.Action("Index", new { page }), PagedListRenderOptions.ClassicPlusFirstAndLast)


回答2:

Below example shows the paging to be done at server side and Client Side : Here is my Model :

 public partial class Employee
    {
        public int Id { get; set; }
        public string FName { get; set; }
        public string Lname { get; set; }
    }

Action:

 public ActionResult Index(int? Page)
    {
        return View();
    }

     /// returns Partial View
    public ActionResult _PartialIndex(int? Page)
    {
        return PartialView(db.Employees.ToList().ToPagedList(Page ?? 1, 10));
    }

Views :

1.Index View :Index.cshtml

@{
    ViewBag.Title = "Index";
}

<script src="https://cdn.jsdelivr.net/jquery.ajax.unobtrusive/3.2.4/jquery.unobtrusive-ajax.min.js"></script>
<script>

    $(document).ready(function () {
        $('#loading').show();
        debugger;
        var Page = '';
        $.ajax({
            url: '/Employees/_PartialIndex',
            contentType: "application/json; charset=utf-8",
            type: 'get',
            datatype: 'html'
        }).success(function (result) {
            $('#main').html(result);
            $('#loading').hide();
        });
    });
</script>
<h2>Index</h2>
<div class="col-md-8 col-md-offset-2">
    <center>
        <div id="loading" style="display:none; z-index:200; position:absolute; top:50%; left:45%;">
            <img src="~/Content/loading.gif" />
        </div>
    </center>
    <div id="main">

    </div>
</div>

2.Partial View :_PartialIndex.cshtml

@using PagedList.Mvc
@using PagedList;
@model IPagedList<samplePaging.Models.Employee>
@{
    ViewBag.Title = "Index";
}

<h2>Employee List</h2>



<table class="table">
    <tr>
        <th>
            First Name
        </th>
        <th>
          Last Name
        </th>
        <th></th>
    </tr>

    @foreach (var item in Model)
    {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.FName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Lname)
            </td>
            <td>
                @Html.ActionLink("Edit", "Edit", new { id = item.Id }) |
                @Html.ActionLink("Details", "Details", new { id = item.Id }) |
                @Html.ActionLink("Delete", "Delete", new { id = item.Id })
            </td>
        </tr>
    }

</table>
<center>
    @Html.PagedListPager(Model, page => Url.Action("_PartialIndex", new {  page }), PagedListRenderOptions.EnableUnobtrusiveAjaxReplacing(new PagedListRenderOptions() { DisplayPageCountAndCurrentLocation = true }, new AjaxOptions() { HttpMethod = "GET", UpdateTargetId = "main", LoadingElementId = "loading" }))
</center>

If you want to do the paging at client side then follow below steps:

Action:

  public ActionResult JsonIndex(int? Page)
        {
            return Json(db.Employees.ToList(), JsonRequestBehavior.AllowGet);
        }

View:

@{
    ViewBag.Title = "Index2";
}

<h2>Index2</h2>

<link rel="stylesheet" type="text/css" href="//cdn.datatables.net/1.10.10/css/jquery.dataTables.min.css">
<script type="text/javascript" language="javascript" src="//cdn.datatables.net/1.10.10/js/jquery.dataTables.min.js"></script>  
<script>


    $(document).ready(function () {
        //Call EmpDetails jsonResult Method
        $.getJSON("/Employees/JsonIndex",
        function (json) {
            var tr;

        //Append each row to html table
        for (var i = 0; i < json.length; i++) {
                tr = $('<tr/>');
                tr.append("<td>" + json[i].FName + "</td>");
                tr.append("<td>" + json[i].LName + "</td>");

                $('table').append(tr);

        }
        $('#EmpInfo').DataTable();
        });

    });

</script> 
<hr />
<div class="form-horizontal">
    <table id="EmpInfo" class="table table-bordered  table-hover">
        <thead>
            <tr>
                <th>Fname</th>
                <th>LName</th>

            </tr>
        </thead>
        <tbody></tbody>
    </table>

</div>   

Hope this help you !