ASP.NET Core MVC分页表格翻页时无法找到控制器动作问题
问题根源与解决方案
你遇到的核心问题是请求方法不匹配:分页链接生成的是GET请求,但控制器里的GetResultList动作只标记了[HttpPost]特性,服务器找不到对应的GET版本处理逻辑,因此返回找不到资源的错误。
详细分析
- 表单提交按钮通过POST请求发送数据到
GetResultList,这和你标记的[HttpPost]动作匹配,所以初始加载第一页数据正常。 - 但分页按钮是
<a>标签,它发起的是GET请求,而你的控制器里没有处理GET请求的GetResultList重载,服务器自然无法找到对应的处理方法。 - 你提到的URL异常(初始URL带
..%2F)是因为初始视图的路由上下文导致Tag Helper修正了路由,但这不是核心问题,核心还是请求方法不匹配。
具体解决方案
1. 添加GET版本的控制器动作
分页需要传递分页参数(page、sortOrder等),同时要保留筛选条件,你需要拆分逻辑,添加一个GET重载来处理分页请求:
// 处理GET请求的分页逻辑 [HttpGet] public async Task<IActionResult> GetResultList(int page = 1, string currentFilter = "", string sortOrder = "") { // 从currentFilter解析筛选条件(这里假设用逗号分隔高低价) int priceLowEnd = 0; int priceHighEnd = int.MaxValue; if (!string.IsNullOrEmpty(currentFilter)) { var filters = currentFilter.Split(','); int.TryParse(filters[0], out priceLowEnd); int.TryParse(filters[1], out priceHighEnd); } // 构建查询(和POST动作里的逻辑一致) var resultsObj = from rd in _db.ResortData join ra in _db.ResortAvailability on rd.RecNo equals ra.RecNoDate where ra.TotalPrice > priceLowEnd && ra.TotalPrice < priceHighEnd select new ResortDealResultsObject { Name = rd.Name, ImageUrl = rd.ImageUrl, ResortDetails = rd.ResortDetails, CheckIn = ra.CheckIn, Address = rd.Address, TotalPrice = ra.TotalPrice }; int pageSize = 3; var model = await PaginatedList<ResortDealResultsObject>.CreateAsync(resultsObj, page, pageSize); ResortDataJoinObj joinObj = new ResortDataJoinObj(); joinObj.PageList = model; ViewBag.rowsReturned = true; ViewData["CurrentSort"] = sortOrder; ViewData["CurrentFilter"] = currentFilter; return View(joinObj); } // 处理POST请求的表单提交 [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> GetResultList(ResortDataJoinObj resDeals, int page = 1) { if (ModelState.IsValid) { // 将筛选条件拼接成currentFilter,重定向到GET动作 string currentFilter = $"{resDeals.priceLowEnd},{resDeals.priceHighEnd}"; return RedirectToAction(nameof(GetResultList), new { page = 1, currentFilter }); } return View(resDeals); }
2. 修正分页链接与额外优化
- 你的原代码中循环创建
resultList是多余的,直接用resultsObj作为PaginatedList.CreateAsync的数据源即可,避免重复代码和潜在的编译错误(循环里的rd/ra未定义)。 - 保留你原来的分页Tag Helper代码即可,确保
ViewData["CurrentFilter"]正确传递筛选条件。 - 价格解析建议用
int.TryParse替代Int32.Parse,避免输入非数字时抛出异常。
内容的提问来源于stack exchange,提问作者loremIpsum1771
相关产品推荐
相关产品推荐

