@Html.DropDownListFor 和@HtmlPagedListPager

@Html.DropDownListFor and @HtmlPagedListPager

我使用 VS2013 创建了一个 MVC 网站。我的视图包含一个 "Import Status" 的下拉列表和一个分页控件,如下所示:

我的看法如下:

@model PagedList.IPagedList<ESBAMPortal.Models.SupplierStockUpdateViewModel>
@using PagedList.Mvc;
<link href="~/Content/PagedList.css" rel="stylesheet"
      type="text/css" />
@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
    SelectList itemsPerPageList = ESBAMPortal.Helpers.DefaultValues.ItemsPerPageList;
}

<h2>Stock Updates</h2>

<div class="container-fluid">
    <div class="row">
        <div id="instruction" class="col-md-6 pull-left">
            <h5>Click the 'Process Start' datetime to see a copy of the file received</h5>
        </div>
    </div>
    <div class="row" id="filters">
        <div id="filtersDropdown" class="col-md-6 pull-right">
            @using (Html.BeginForm("Index", "SupplierStockUpdate", FormMethod.Get, new { @class = "pull-right" }))
            {
                {
                    <span>
                        @Html.Label("Import Status:")
                        @Html.DropDownListFor(m => m.FirstOrDefault().SelectedStatusId, Model.FirstOrDefault().StatusItems)
                     </span>
                    <span>
                        @Html.Label("Items per page:")
                        @Html.DropDownList("ItemsPerPage", itemsPerPageList,
                            new { @id = "ItemsPerPageList" })
                    </span>
                }
                <input type="submit" value="Refresh" />
            }
        </div>
    </div>
</div>

<table class="table table-striped">
    <thead>
        <tr>
            <th>@Html.DisplayNameFor(model => model.FirstOrDefault().ReceivedFilename)</th>
            <th>@Html.ActionLink("Proces Start", "Index", new { sortOrder = ViewBag.TimeReceivedSort, itemsPerPage = itemsPerPageList.SelectedValue })</th>
            <th>@Html.DisplayNameFor(model => model.FirstOrDefault().TimeProductLookupResponse)</th>
            <th>@Html.DisplayNameFor(model => model.FirstOrDefault().TimeInsertResponse)</th>
            <th>@Html.DisplayNameFor(model => model.FirstOrDefault().ImportStatus)</th>
            <th>@Html.DisplayNameFor(model => model.FirstOrDefault().ImportErrors)</th>
            <th>@Html.ActionLink("Supplier", "Index", new { sortOrder = ViewBag.SupplierSort })</th>
            <th>@Html.DisplayNameFor(model => model.FirstOrDefault().RowsInserted)</th>

            <th>@Html.DisplayNameFor(model => model.FirstOrDefault().TimeOfExceptionString)</th>
        </tr>
    </thead>

    <tbody>
        @foreach (var item in Model)
        {

            <tr>
                <td>@Html.DisplayFor(model => item.ReceivedFilename)</td>
                <td>
                    @Html.ActionLink(item.TimeReceived.ToString(), "Index", "ArchivedMsg",
                        new { interchangeId = item.InterchangeId }, null)
                </td>
                <td>@Html.DisplayFor(model => item.TimeProductLookupResponse)</td>
                <td>@Html.DisplayFor(model => item.TimeInsertResponse)</td>
                <td>@Html.DisplayFor(model => item.ImportStatus)</td>
                <td>@Html.DisplayFor(model => item.ImportErrors)</td>
                <td>@Html.DisplayFor(model => item.SupplierCode)</td>
                <td>@Html.DisplayFor(model => item.RowsInserted)</td>
                @{

            if (item.TimeOfExceptionString.IsDateTime())
            {
                <td>@Html.ActionLink(item.TimeOfExceptionString, "IndexForInterchangeId", "Fault", new { interchangeId = item.InterchangeId }, null) </td>
            }
            else
            {
                <td>NA</td>
            }
                }
            </tr>
        }
    </tbody>
</table>

<div id="pageControllFooter" class="container-fluid">
    <div class="row">
        <div id="pageButtons" class="col-md-2">
            @Html.PagedListPager(Model, page => Url.Action("Index", new { page, itemsPerPage = ViewBag.CurrentItemsPerPage }))
        </div>
    </div>
    <div class="row">
        <div id="pageDesc" class="col-md-2">
            @if (Model != null
                    && Model.PageCount > 0)
            {
                <div>
                    Page @(Model.PageCount < Model.PageNumber
                     ? 0 : Model.PageNumber)
                    of @Model.PageCount
                </div>
            }
        </div>

    </div>
</div>

型号:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace ESBAMPortal.Models
{
    public class SupplierStockUpdateViewModel
    {
        public string ActivityID { get; set; }
        public string InterchangeId { get; set; }

        [DisplayName("Received")]
        public DateTime? TimeReceived { get; set; }
        [DisplayName("DW Product Requested")]
        public DateTime? TimeProductLookupRequested { get; set; }
        [DisplayName("DW Product Response")]
        public DateTime? TimeProductLookupResponse { get; set; }
        [DisplayName("CIMS Insert Requested")]
        public DateTime? TimeInsertRequested { get; set; }
        [DisplayName("CIMS Insert Response")]
        public DateTime? TimeInsertResponse { get; set; }
        [DisplayName("Supplier Code")]
        public string SupplierCode { get; set; }
        [DisplayName("CIMS Records Updated")]
        public int? RowsInserted { get; set; }
        public string ReceivedFilename { get; set; }
        public DateTime? TimeOfException { get; set; }
        public string TimeOfExceptionString { get; set; }
        public double TotalDuration { get; set; }
        public string ImportStatus { get; set; }
        public int? ImportErrors { get; set; }
        public DateTime LastModified { get; set; }

        //constructor
        public SupplierStockUpdateViewModel()
        {
            _statuses = new List<Status>();

            _statuses.Add(new Status()
            {
                Id = 1,
                Name = "All"
            });

            _statuses.Add(new Status()
            {
                Id = 2,
                Name = "Pending"
            });

            _statuses.Add(new Status()
            {
                Id = 3,
                Name = "Complete"
            });

        }

        private readonly List<Status> _statuses;

        public class Status
        {
            public int Id { get; set; }
            public string Name { get; set; }
        }

        [Display(Name = "Status")]
        public int SelectedStatusId { get; set; }

        //our VM has a select list
        public IEnumerable<SelectListItem> StatusItems
        {
            get { return new SelectList(_statuses, "Id", "Name"); }
        }
    }

}

控制器:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ESBAMPortal.DataLayer;
using ESBAMPortal.Models;
using PagedList;
using ESBAMPortal.DomainClasses.BAM;
using System.IO;

namespace ESBAMPortal.Controllers
{
    public class SupplierStockUpdateController : Controller
    {
        private IRepository<SupplierStockUpdate> SupplierStockUpdateRepository;

        public SupplierStockUpdateController(BAMContext context)
        {
            this.SupplierStockUpdateRepository = new EFRepository<SupplierStockUpdate>(context);
        }

        private string TranslateStatusFilter(int status)
        {
            string ret = "";

            switch (status)
            {
                case 2:
                    ret = "Pending";
                    break;
                case 3:
                    ret = "Complete";
                    break;
            }

            return ret;

        }

        // GET: /SupplierStock/
        public ActionResult Index(string sortOrder, int? page, int? itemsPerPage, SupplierStockUpdateViewModel vm)
        {

            string statusFilter = TranslateStatusFilter(vm.SelectedStatusId);

            ViewBag.CurrentItemsPerPage = itemsPerPage;
            ViewBag.TimeReceivedSort = String.IsNullOrEmpty(sortOrder) ? "timeReceived" : "";
            ViewBag.SupplierSort = sortOrder == "supplier" ? "supplier_desc" : "supplier";

            var query = this.SupplierStockUpdateRepository.GetAll();
            switch (sortOrder)
            {
                case "timeReceived":
                    query = query.OrderBy(f => f.TimeReceived);
                    break;
                case "supplier":
                    query = query.OrderBy(f => f.SupplierCode);
                    break;
                case "supplier_desc":
                    query = query.OrderByDescending(f => f.SupplierCode);
                    break;
                default:
                    query = query.OrderByDescending(f => f.TimeReceived);
                    break;
            }

            if (statusFilter == "Pending" || statusFilter == "Complete")
            {
                query = query.Where(x => x.ImportStatus == statusFilter);
            }

            //shove results into view model
            List<SupplierStockUpdateViewModel> SupplierStockUpdatesVM = new List<SupplierStockUpdateViewModel>();

            DateTime start = new DateTime();
            DateTime end = new DateTime();

            foreach (var item in query.ToList())
            {
                SupplierStockUpdateViewModel SupplierStockUpdateVM = new SupplierStockUpdateViewModel();

                SupplierStockUpdateVM.ActivityID = item.ActivityID;
                SupplierStockUpdateVM.InterchangeId = item.InterchangeId;
                SupplierStockUpdateVM.TimeReceived = item.TimeReceived;
                SupplierStockUpdateVM.TimeProductLookupRequested = item.TimeProductLookupRequested;
                SupplierStockUpdateVM.TimeProductLookupResponse = item.TimeProductLookupResponse;
                SupplierStockUpdateVM.TimeInsertRequested = item.TimeInsertRequested;
                SupplierStockUpdateVM.TimeInsertResponse = item.TimeInsertResponse;
                SupplierStockUpdateVM.SupplierCode = item.SupplierCode;
                SupplierStockUpdateVM.RowsInserted = item.RowsInserted;
                SupplierStockUpdateVM.TimeOfException = item.TimeOfException;
                SupplierStockUpdateVM.ReceivedFilename = item.ReceivedFilename;
                SupplierStockUpdateVM.ImportStatus = item.ImportStatus;
                SupplierStockUpdateVM.ImportErrors = item.ImportErrors;

                start = (item.TimeReceived == null) ? DateTime.MinValue : (System.DateTime)item.TimeReceived;

                if (item.TimeOfException == null)
                {
                    SupplierStockUpdateVM.TimeOfExceptionString = "NA";
                    if (item.TimeInsertResponse != null)
                    {
                        end = (System.DateTime)item.TimeInsertResponse;
                    }
                    else
                    {
                        //no exception but process still running so give a duration of 0
                        end = start;
                    }
                }
                else
                {
                    SupplierStockUpdateVM.TimeOfExceptionString = item.TimeOfException.ToString();
                    end = (System.DateTime)item.TimeOfException;
                }

                if (start == DateTime.MinValue)
                {
                    SupplierStockUpdateVM.TotalDuration = 0;
                }
                else
                {
                    SupplierStockUpdateVM.TotalDuration = (end - start).TotalSeconds;
                }

                SupplierStockUpdatesVM.Add(SupplierStockUpdateVM);
            }

            int pageSize = (itemsPerPage ?? 10);
            int pageNumber = (page ?? 1);

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

单击 "Refesh" 按钮一切正常,过滤后的导入状态将传递给控制器​​。我的问题是,当通过单击页面控件的框进行分页时,值 0 始终传递到 VM.SelectedStatusId 字段中。

我已尝试更改视图的调用以显式传递 SelectedStatusId,如下所示:

@Html.PagedListPager(Model, page => Url.Action("Index", new { page, itemsPerPage = ViewBag.CurrentItemsPerPage, Model.FirstOrDefault().SelectedStatusId }))

...并在控制器操作上添加了一个相应的 int 参数,但这仍然是 0。

谁能告诉我哪里出错了?谢谢。

乍一看,您似乎将以下行编码错了。

    @Html.PagedListPager(Model, page => Url.Action("Index", new { page, itemsPerPage = ViewBag.CurrentItemsPerPage, Model.FirstOrDefault().SelectedStatusId }))

您忘记了表达式中最后一个参数的 return 参数。尝试以下

    @Html.PagedListPager(Model, page => Url.Action("Index", new { page, itemsPerPage = ViewBag.CurrentItemsPerPage, vm = Model.FirstOrDefault().SelectedStatusId }))

注意 "vm = "

如果可行,请告诉我!

当用户单击视图上的 "Refresh" 按钮时,vm.SelectedStatusId 被传递到操作中。

我在控制器的Index动作中将选中的状态分配给viewbag属性:

ViewBag.StatusId = vm.SelectedStatusId;

当用户稍后翻阅结果时,我从 viewbag 中传入先前选择的状态过滤器:

 @Html.PagedListPager(Model, page => Url.Action("Index", new { page, itemsPerPage = ViewBag.CurrentItemsPerPage, selectedStatusId = ViewBag.StatusId }))