问题
I am using PagedList.Mvc and I have added a nice way to navigate across various pages in a mvc web application. However, when I click on an "edit" or "details" tab and save changes I am sent back to the 1st page. I want to remain on the same page where the changes were made.
Here is the code I have in the controller:
// GET: Item
public ActionResult Index(int? page)
{
var items = db.Items.Include(i => i.PurchaseOrder);
return View(items.ToList().ToPagedList(page ?? 1, 3));
}
Here is the code I have in the view:
@using PagedList;
@using PagedList.Mvc;
@model IPagedList<PurchaseOrders.Models.Item>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.First().ItemDescription)
</th>
<th>
@Html.DisplayNameFor(model => model.First().Quantity)
</th>
<th>
@Html.DisplayNameFor(model => model.First().Price)
</th>
<th>
@Html.DisplayNameFor(model => model.First().DueDate)
</th>
<th>
@Html.DisplayNameFor(model => model.First().DateReceived)
</th>
<th>
@Html.DisplayNameFor(model => model.First().Comments)
</th>
<th>
@Html.DisplayNameFor(model => model.First().PurchaseOrder.PurchaseRequest_)
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.ItemDescription)
</td>
<td>
@Html.DisplayFor(modelItem => item.Quantity)
</td>
<td>
@Html.DisplayFor(modelItem => item.Price)
</td>
<td>
@Html.DisplayFor(modelItem => item.DueDate)
</td>
<td>
@Html.DisplayFor(modelItem => item.DateReceived)
</td>
<td>
@Html.DisplayFor(modelItem => item.Comments)
</td>
<td>
@Html.DisplayFor(modelItem => item.PurchaseOrder.PurchaseRequest_)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.ItemId }) |
@Html.ActionLink("Details", "Details", new { id=item.ItemId }) |
@Html.ActionLink("Delete", "Delete", new { id=item.ItemId })
</td>
</tr>
}
</table>
@Html.PagedListPager(Model, page => Url.Action("Index", new { page }))
Please help!
回答1:
You could pass an additional 'page` parameter to your edit method, for example
In your Index method, add
ViewBag.CurrentPage = page; // or use a view model property
Then your link would be
@Html.ActionLink("Edit", "Edit", new { id=item.ItemId, page = ViewBag.CurrentPage})
Then your edit method
[HttpGet]
public ActionResult Edit(int ID, int page)
{
ViewBag.CurrentPage = page; // pass current page to edit view
And your edit view
@using (Html.BeginForm(new { page = ViewBag.CurrentPage })) {
And in you post method
[HttpGet]
public ActionResult Edit(EditModel model, int page)
{
.... // Save
return RedirectToAction("Index", new { page = page });
回答2:
In this case the page is stored in the ViewBag which makes it ephemeral (the ViewBag is only available for the current request).
In the controller, you're telling it if you get null use 1 as your current page. so null is always retuned and you get the 1st page everytime.
You need to provide the current page Number to your views that you navigate to (Edit/Create) and then provide it back to the original page when you're done. You can use the TempData,that works well on HTTP redirects and lives longer than viewbag or viewData. You can also move it arround with your models when calling actions and then give it back to the index action that needs a page number. You can use sessions too. BTW, TempData is using session behind the scenes. UPDATED: Code to add in your index action:
var page = TempData["page"];
Code to add in the Create or Edit Submit action
//Get the page number
var page = TempData["page"];
//Set it back to Tempdata (because Tempdata is only for redirects) otherwise it will be lost
TempData["page"]=page;
add the value of the parameter to TempData["page"] when calling back the index action again You can also access it from Index action directly since we repopulated it:
var page = TempData["page"];
return View(items.ToList().ToPagedList(page ?? 1, 3));
回答3:
I also had this problem.
I tried to put it in the URL at first but it seems a bit weird to have ?page=2
in our URL.
So I replaced it with using TempData
What you need to do is this:
Store the page in TempData
when you are in your Index()
action method;
public const string PAGE_QUERY_STRING_KEY = "page";
public ActionResult Index(int page = 1)
{
TempData[PAGE_QUERY_STRING_KEY] = page;
...
}
Then use TempData.Peek()
, instead of TempData[]
, everywhere else (to retain the value of your page between requests which are related to your current Index
page) --- in your Edit, Create, Details, etc. action methods:
public ActionResult Edit(...)
{
...
return RedirectToAction(nameof(Index), new { page = TempData.Peek(PAGE_QUERY_STRING_KEY) });
// do not do this because this will remove the temp data
// return RedirectToAction(nameof(Index), new { page = TempData[PAGE_QUERY_STRING_KEY])
}
... and in your views:
<!--(Edit.cshtml)-->
...
<p>
@Html.ActionLink("Back to List", "Index",
new { page = TempData.Peek(FLP.Web.Controllers.UsersAdminController.PAGE_QUERY_STRING_KEY) })
</p>
来源:https://stackoverflow.com/questions/25271610/how-to-remain-retain-on-the-same-page-when-using-pagedlist-mvc