下拉框选择后已获取数据但Razor Pages页面未加载新数据问题
问题描述
- 下拉框选中值会作为参数传入存储过程,目前已成功从数据库获取对应数据,但新数据无法加载到当前页面
- PageA初始加载时可正常渲染初始数据与下拉选择控件,预期选中下拉框选项后使用新拉取的数据刷新PageA,但页面始终渲染旧数据。已确认可正常获取下拉选中值对应的数据库数据,仅存在新数据无法加载到PageA的问题。
相关代码
PageA.cshtml
@foreach (IcebergeWebApplication.Models.UserManager User_det in Model.UserManager) { <tr> <td align="right">User:</td> <td colspan="2"> <select name="lstuser" width="15px" id="lstuser" onchange="Checked()"> @foreach (IcebergeWebApplication.Models.UserManager1 user_det1 in Model.UserManager1) { if (User_det.user == user_det1.user) { <option selected="selected" value="@user_det1.id_login"> @user_det1.user </option> } else { <option value="@user_det1.id_login">@user_det1.user</option> } } </select> </td> <td rowspan="7"> <table border="1" cellspacing="0" cellpadding="1"> <tr> <td>ACNA Site(s)</td> </tr> <tr> <td valign="top"> <table border="0" cellspacing="0" cellpadding="1" id="acnaSiteContainer"> @foreach (IcebergeWebApplication.Models.acna_site acna_Site in Model.acna_site) { <tr> <td> <input type="checkbox" name="chkACNASites" class="chkACNASites"/> </td> </tr> } </table> </td> </tr> </table> </td> </tr> } <script> function Checked() { var selected = document.getElementById('lstuser').value; alert(selected); $.getJSON(`?handler=SelectuserId&UserId=${selected}`, (data) => {}); } </script>
PageA.cshtml.cs
public async Task<IActionResult> OnGet() { return Page(); } public void OnGetSelectuserId(int UserId) { HttpContext.Session.SetInt32("SelectedUserID",UserId); OnGet(); }
问题根因
- 前端AJAX请求回调为空:
$.getJSON的回调函数没有任何逻辑,就算后端返回数据,前端也不会更新DOM - 后端Handler逻辑错误:
OnGetSelectuserId是void返回类型,内部调用OnGet()只会在服务端执行方法逻辑,不会把渲染好的页面/查询到的数据返回给前端请求 - 数据绑定逻辑缺失:把用户ID存入Session后,没有重新查询对应用户的关联数据赋值给PageModel属性,就算触发页面渲染,Model里还是初始加载的旧数据
- 代码规范问题:多个checkbox使用了重复的id
chkACNASites,违反HTML id全局唯一的规范,会导致DOM选择异常
修复方案
提供两种实现方案,按需选择即可。
方案1:全页刷新(改动最小,逻辑简单)
- 修改后端
OnGet方法,支持接收UserId参数,优先读取Session/传入的用户ID查询数据绑定Model:
public async Task<IActionResult> OnGet(int? UserId) { // 优先用传入的UserId更新Session if(UserId.HasValue) { HttpContext.Session.SetInt32("SelectedUserID", UserId.Value); } // 读取当前选中的用户ID,没有就取默认值 int selectedUid = HttpContext.Session.GetInt32("SelectedUserID") ?? 1; // 以下替换成你自己的存储过程/数据库查询逻辑,用selectedUid查询对应数据赋值给Model // Model.UserManager = 查用户数据逻辑 // Model.UserManager1 = 查下拉选项数据逻辑 // Model.acna_site = 查对应用户关联的ACNA站点数据逻辑 return Page(); }
- 修改
OnGetSelectuserId方法,用重定向代替直接调用OnGet:
public IActionResult OnGetSelectuserId(int UserId) { HttpContext.Session.SetInt32("SelectedUserID", UserId); // 重定向到当前页,自动触发OnGet逻辑重新加载全量数据 return RedirectToPage(); }
- 前端修改Checked方法,去掉空AJAX请求,直接触发页面跳转:
function Checked() { var selected = document.getElementById('lstuser').value; window.location.search = `?UserId=${selected}`; }
方案2:AJAX局部刷新(无整页刷新,体验更好)
- 修改后端
OnGetSelectuserId方法,返回查询到的站点数据:
public JsonResult OnGetSelectuserId(int UserId) { // 替换成你的存储过程查询逻辑,查询传入UserId对应的ACNA站点列表 var siteList = 数据库查询ACNA站点的逻辑; return new JsonResult(siteList); }
- 前端补全AJAX回调逻辑,拿到新数据后局部更新站点列表区域:
function Checked() { var selected = document.getElementById('lstuser').value; $.getJSON(`?handler=SelectuserId&UserId=${selected}`, (data) => { const container = document.getElementById('acnaSiteContainer'); // 清空旧数据 container.innerHTML = ''; // 遍历新数据生成DOM data.forEach(site => { const tr = document.createElement('tr'); const td = document.createElement('td'); const checkbox = document.createElement('input'); checkbox.type = 'checkbox'; checkbox.name = 'chkACNASites'; checkbox.className = 'chkACNASites'; // 如果你需要给checkbox赋值,在这里加逻辑,比如checkbox.value = site.id; td.appendChild(checkbox); tr.appendChild(td); container.appendChild(tr); }); }); }
注意:需要给站点列表的内层table加上idacnaSiteContainer方便定位,同时把重复的checkbox id改成class,避免DOM选择异常。
内容的提问来源于stack exchange,提问作者Swapnil Mahajan
相关产品推荐
相关产品推荐

