ASP.NET MVC 5下拉框联动:根据生产区域筛选缺陷下拉框
实现ASP.NET MVC 5级联下拉框(根据生产区域过滤缺陷)
核心问题分析
你之前的错误在于前端脚本中直接编写C#后端代码(比如db.Defect_info.Where、ViewBag操作)——前端JS运行在浏览器,无法直接访问后端的数据库上下文和服务器端的ViewBag;另外页面重定向会丢失表单状态,必须用异步AJAX请求实现无刷新更新。
解决方案步骤
1. 后端新增AJAX接口(返回过滤后的缺陷数据)
在你的控制器中添加一个专门处理缺陷数据查询的Action,返回JSON格式的选项列表:
[HttpGet] public JsonResult GetDefects(int productionAreaId) { // 从数据库查询对应生产区域的缺陷,只返回需要的ID和名称 var defectOptions = db.Defect_info .Where(d => d.Production_area_id == productionAreaId) .Select(d => new { Value = d.Defect_id, Text = d.Defect_name }) .ToList(); // 允许GET请求获取JSON(MVC默认限制,需显式开启) return Json(defectOptions, JsonRequestBehavior.AllowGet); }
2. 修复前端AJAX脚本
替换你原来的GetDefects函数,用jQuery发送异步请求,动态更新缺陷下拉框:
function GetDefects(val) { $.ajax({ // 使用Url.Action生成正确的路由地址,避免硬编码 url: '@Url.Action("GetDefects")', type: 'GET', data: { productionAreaId: val }, success: function (data) { // 找到缺陷下拉框元素 var defectDropdown = $('#Defect_id'); // 清空原有选项 defectDropdown.empty(); // 添加默认提示选项 defectDropdown.append('<option value="">请选择缺陷</option>'); // 遍历返回的数据,添加新选项 $.each(data, function (index, item) { defectDropdown.append(`<option value="${item.Value}">${item.Text}</option>`); }); }, error: function () { alert('加载缺陷数据失败,请重试'); } }); }
注意:确保你的页面已经引用了jQuery(MVC默认模板的_Layout.cshtml中已包含,若未引用需添加
<script src="~/Scripts/jquery-3.4.1.min.js"></script>)
3. 调整缺陷下拉框的部分视图(_DefectDropdown.cshtml)
确保下拉框的ID为Defect_id,以便JS能正确选中:
<div class="form-group"> @Html.LabelFor(model => model.Defect_id, "缺陷", htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.DropDownList("Defect_id", null, "请选择缺陷", htmlAttributes: new { @class = "form-control" }) @Html.ValidationMessageFor(model => model.Defect_id, "", new { @class = "text-danger" }) </div> </div>
4. 修正Create控制器的初始化逻辑
去掉原来错误的ViewBag分支判断,初始化下拉框并处理用户默认生产区域:
public ActionResult Create() { string empid = Request.Cookies.AllKeys.Contains("userid") ? Request.Cookies["userid"].Value : "??"; int? defaultProdAreaId = null; // 修复SQL注入风险:使用参数化查询 using (var con = new SqlConnection(/* 替换为你的数据库连接字符串 */)) { con.Open(); SqlCommand cmd = new SqlCommand("Select Production_area_id from Employee where Employee_id = @empid", con); cmd.Parameters.AddWithValue("@empid", empid); SqlDataAdapter adp = new SqlDataAdapter(cmd); DataTable dtt = new DataTable(); adp.Fill(dtt); if (dtt.Rows.Count > 0) { defaultProdAreaId = Convert.ToInt32(dtt.Rows[0]["Production_area_id"]); } } // 初始化各下拉框 ViewBag.userid = empid; // 初始缺陷下拉框为空,后续通过AJAX填充 ViewBag.Defect_id = new SelectList(Enumerable.Empty<SelectListItem>(), "Value", "Text"); ViewBag.Employee_id = new SelectList(db.Employees, "Employee_id", "Employee_fullname", empid); ViewBag.Production_area_id = new SelectList(db.Production_area, "Production_area_id", "Production_area_name", defaultProdAreaId); ViewBag.Production_area_assigned_id = new SelectList(db.Production_area, "Production_area_id", "Production_area_name", defaultProdAreaId); // 传递默认生产区域ID,用于页面加载时自动填充缺陷 if (defaultProdAreaId.HasValue) { ViewBag.DefaultProdAreaId = defaultProdAreaId.Value; } return View(); }
5. 页面加载时自动填充默认缺陷(可选)
在Create.cshtml底部添加脚本,页面加载完成后自动触发一次缺陷查询(如果有默认生产区域):
$(document).ready(function() { var defaultProdId = '@ViewBag.DefaultProdAreaId'; if (defaultProdId) { GetDefects(defaultProdId); } });
关键注意事项
- 避免SQL注入:永远不要直接拼接用户输入到SQL语句中,使用参数化查询。
- 路由正确性:用
Url.Action生成接口地址,避免硬编码导致部署后路径错误。 - AJAX跨域/权限:如果你的项目有身份验证,确保AJAX请求能携带用户凭证(比如配置
$.ajaxSetup({ xhrFields: { withCredentials: true } }))。
内容的提问来源于stack exchange,提问作者Steve Link
相关产品推荐
相关产品推荐

