.NET Core 6 Razor Pages级联下拉列表实现方案咨询
.NET Core 6 Razor Pages 级联下拉列表实现方案
先明确两个核心问题的结论:
- AJAX是当前场景下轻量化、适配度最高的实现方案,无需引入额外前端框架即可完成无刷新交互
- 配合返回
JsonResult的后端处理方法是Razor Pages实现这类联动需求的标准做法,和你现有EF、内存缓存的代码逻辑完全兼容
具体实现步骤
1. 后端添加级联查询接口
你现有的OnGet方法负责页面首次加载的数据渲染,额外新增一个Get请求处理方法,接收前端传的选中课程ID,返回对应关联的距离列表即可,缓存逻辑和你现有代码保持一致,避免重复查库:
public JsonResult OnGetDistancesByCourse(int courseId) { List<MedianTimes> allTimes; // 复用现有内存缓存逻辑 if (DataInMemoryCache.GetFromCache(_medianTimesCacheKey) != null) { allTimes = (List<MedianTimes>)DataInMemoryCache.GetFromCache(_medianTimesCacheKey); } else { allTimes = _medianTimesDbContext.MedianTimes.ToList(); DataInMemoryCache.AddToCache(_medianTimesCacheKey, allTimes); } // 注意:这里的关联字段按你实际的表结构替换,示例用CourseId作为外键 var filteredDistances = allTimes .Where(t => t.CourseId == courseId) .Select(t => new { value = t.RowId, text = t.Distance }) .ToList(); return new JsonResult(filteredDistances); }
小提示:首次加载的OnGet方法里,不要加载全量的MedianTimes,取默认选中的第一个课程ID做筛选即可,和联动逻辑保持一致。
2. 前端绑定下拉切换事件
你现有的HTML结构基本不用改,只需要在页面脚本区域给课程下拉绑定change事件,选中项变化时请求上面写的后端接口,拿到数据后重绘距离下拉就行,原生JS就能实现,不需要额外依赖:
<label>Course</label> <select id="ddlCourse" name="ddlCourse"> @foreach (var row in Model.Courses) { <option value="@row.Id.ToString()">@row.Course</option> } </select> <label>Course Distance</label> <select id="ddlDistance" name="ddlDistance"> @foreach (var row in Model.MedianTimes) { <option value="@row.RowId">@row.Distance</option> } </select> @section Scripts { <script> const courseSelect = document.getElementById('ddlCourse'); const distanceSelect = document.getElementById('ddlDistance'); // 订阅课程下拉的选中变化事件 courseSelect.addEventListener('change', async function() { const selectedCourseId = this.value; // 清空旧选项,显示加载状态 distanceSelect.innerHTML = '<option value="">加载中...</option>'; try { // Razor Pages约定:命名为OnGetXxx的方法,请求路径为?handler=Xxx const res = await fetch(`?handler=DistancesByCourse&courseId=${selectedCourseId}`); if (!res.ok) throw new Error('接口请求异常'); const distanceOptions = await res.json(); // 重绘距离下拉选项 distanceSelect.innerHTML = ''; distanceOptions.forEach(opt => { const optionEl = document.createElement('option'); optionEl.value = opt.value; optionEl.textContent = opt.text; distanceSelect.appendChild(optionEl); }); } catch (err) { distanceSelect.innerHTML = '<option value="">加载失败,请刷新重试</option>'; console.error(err); } }); </script> }
注意事项
- 后端筛选逻辑里的关联字段(示例里的
t.CourseId)要替换成你实际业务中MedianTimes和Courses的关联字段,不要直接复制使用 - 这里用Get请求拉取选项数据,不需要额外处理Razor Pages的防伪造令牌校验,如果后续改成Post提交,记得在请求头里带上
RequestVerificationToken - 整个逻辑完全复用你现有的缓存、EF数据访问代码,不会额外增加性能开销
- 如果项目里已经引入了jQuery,把原生
fetch换成$.get写法逻辑完全一致,不影响功能
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

