ASP.NET MVC食谱博客分类下拉筛选功能实现求助
问题解决:食谱博客分类筛选与路由冲突修复
问题根源
- 路由冲突:多个同名
[HttpPost] Index方法导致ASP.NET Core无法区分请求,抛出路由匹配异常 - 筛选异常:分类下拉框无
name属性,提交时无法传递参数;同时枚举默认值为0(Veg),未传值时会自动匹配素食分类,导致筛选结果异常
解决方案
1. 统一Controller逻辑(解决路由冲突+筛选逻辑)
合并搜索与分类筛选到单一[HttpPost]方法,使用可空枚举处理"全部"分类的场景:
// GET请求:初始加载/重置筛选 [HttpGet] public async Task<IActionResult> Index() { IEnumerable<Post> posts = await _postInterface.GetAll(); return View(posts); } // POST请求:处理搜索+分类筛选 [HttpPost] public async Task<IActionResult> Index(string? searchString, PostCategory? postCategory) { var posts = _context.Posts.AsQueryable(); // 处理关键词搜索 if (!string.IsNullOrEmpty(searchString)) { posts = posts.Where(t => t.Title!.Contains(searchString)); ViewData["CurrentSearch"] = searchString; // 保留搜索状态 } // 处理分类筛选:仅当分类参数有值时过滤 if (postCategory.HasValue) { posts = posts.Where(c => c.PostCategory == postCategory.Value); ViewData["CurrentCategory"] = postCategory.Value; // 保留分类选中状态 } return View(await posts.ToListAsync()); }
2. 修复View表单(解决参数传递问题)
合并搜索与分类筛选为单一表单,给下拉框添加正确的name属性,同时保留筛选状态:
<!-- 合并搜索+分类筛选表单 --> <div class="row justify-content-between"> <div class="col-8"> <form class="d-flex mb-2" role="search" asp-controller="Post" asp-action="Index"> <!-- 搜索框:保留上次搜索词 --> <input class="form-control me-2" type="search" placeholder="Search Posts" aria-label="Search" name="searchString" value="@ViewData["CurrentSearch"]" /> <!-- 分类下拉框:添加name属性,保留选中状态 --> <select class="form-control me-2" name="postCategory" asp-items="@Html.GetEnumSelectList<PostCategory>()" asp-for="@ViewData["CurrentCategory"]"> <option value="">All</option> </select> <button class="btn btn-outline-success me-2" type="submit">Filter</button> <a class="btn btn-outline-danger" asp-controller="Post" asp-action="Index">Reset</a> </form> </div> </div> <!-- 卡片展示部分保持不变 --> <div class="album py-5 bg-light"> <div class="container"> <div class="row row-cols-1 row-cols-sm-2 row-cols-md-3 g-3" id="post-recipe"> @foreach (var item in Model) { <div class="col mb-4"> <div class="card shadow-sm"> <img class="bd-placeholder-img card-img-top" src="@item.Image" width="157" height="236" alt="Card image cap"> <div class="card-body"> <a asp-controller="Post" asp-action="Detail" asp-route-id="@item.Id" class="stretched-link"></a> <h6 class="card-text"> @item.Title </h6> <div class="d-flex justify-content-between align-items-center"> <small class="text-body-secondary">@item.PostCategory</small> </div> </div> <div class="card-footer btn-group"> <a asp-controller="Post" asp-action="Edit" asp-route-id="@item.Id" type="button" class="btn btn-sm btn-outline-primary stretched-link">Edit</a> <a asp-controller="Post" asp-action="Delete" asp-route-id="@item.Id" type="button" class="btn btn-sm btn-outline-danger stretched-link">Delete</a> </div> </div> </div> } </div> </div> </div>
关键说明
- 路由冲突解决:仅保留一个
[HttpPost] Index方法,通过可选参数覆盖搜索、分类、搜索+分类三种筛选场景 - 筛选异常解决:
- 下拉框添加
name="postCategory",确保表单提交时参数能正确绑定到Controller - 使用
PostCategory?可空枚举,当选择"All"(空值)时跳过分类筛选,显示所有文章 - 新增
ViewData存储筛选状态,让页面提交后保留用户的搜索词和分类选择
- 下拉框添加
内容的提问来源于stack exchange,提问作者ZNAXNOR
相关产品推荐
相关产品推荐

