ASP.NET Core 3.1 MVC Ajax级联下拉框无法填充问题求助
问题诊断与修复
核心问题:Ajax未触发的原因
你的site.js中选择器错误,ID选择器必须以#开头,原代码$("ddlArea")无法匹配到ID为ddlArea的下拉框,导致change事件绑定失败。
分步修复
1. 修正site.js的选择器
将:
$("ddlArea").change(function () {
改为:
$("#ddlArea").change(function () {
2. 修复存储过程参数类型
存储过程getTeamsByAreaId的参数未指定数据类型,会导致执行报错:
CREATE PROCEDURE [ddl].[getTeamsByAreaId] @AreaId INT -- 补充参数类型 AS BEGIN SELECT * FROM [ddl].[Team] WHERE AreaId = @AreaId END
3. 确保JS文件正确加载
视图中引用site.js的路径需要正确解析,Razor视图中应使用asp-src或绝对路径:
<script src="~/js/site.js" asp-append-version="true"></script>
若site.js在wwwroot/js目录下,也可直接用绝对路径:
<script src="/js/site.js"></script>
4. 控制器方法添加HttpGet特性
为GetTeamList方法添加[HttpGet]特性,明确允许GET请求:
[HttpGet] public JsonResult GetTeamList(int areaid) { // 原有代码保持不变 }
5. 规范ADO类的连接使用
在ADO类中使用using块确保连接自动释放,避免资源泄漏:
public DataSet GetAllAreas() { using (SqlConnection conn = new SqlConnection("Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=CentralMISData;Integrated Security=True;")) { SqlCommand cmd = new SqlCommand("ddl.getAllAreas", conn) { CommandType = CommandType.StoredProcedure }; SqlDataAdapter da = new SqlDataAdapter(cmd); DataSet ds = new DataSet(); da.Fill(ds); return ds; } } public DataSet GetTeamByAreaId(int areaId) { using (SqlConnection conn = new SqlConnection("Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=CentralMISData;Integrated Security=True;")) { SqlCommand cmd = new SqlCommand("ddl.getTeamByAreaId", conn) { CommandType = CommandType.StoredProcedure }; cmd.Parameters.AddWithValue("@AreaId", areaId); SqlDataAdapter da = new SqlDataAdapter(cmd); DataSet ds = new DataSet(); da.Fill(ds); return ds; } }
更优方案:使用EF Core替代ADO.NET
既然你基于EF Core项目开发,直接利用EF Core的LINQ查询会更简洁易维护,无需手动编写存储过程和ADO代码:
1. 定义实体类
namespace CentralMISData.Models { public class Area { public int AreaId { get; set; } public string AreaName { get; set; } public ICollection<Team> Teams { get; set; } } public class Team { public int TeamId { get; set; } public string TeamName { get; set; } public int AreaId { get; set; } public Area Area { get; set; } } }
2. 配置DbContext
using Microsoft.EntityFrameworkCore; using CentralMISData.Models; namespace CentralMISData.Data { public class AppDbContext : DbContext { public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { } public DbSet<Area> Areas { get; set; } public DbSet<Team> Teams { get; set; } } }
3. 简化控制器代码
using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using CentralMISData.Data; using CentralMISData.Models; namespace CentralMISData.Controllers { public class HomeController : Controller { private readonly AppDbContext _context; private readonly ILogger<HomeController> _logger; public HomeController(AppDbContext context, ILogger<HomeController> logger) { _context = context; _logger = logger; } public IActionResult Index() { return View(); } public async Task<IActionResult> Privacy() { var areas = await _context.Areas.ToListAsync(); ViewBag.Arealist = areas.Select(a => new SelectListItem { Text = a.AreaName, Value = a.AreaId.ToString() }).ToList(); return View(); } [HttpGet] public async Task<JsonResult> GetTeamList(int areaid) { var teams = await _context.Teams.Where(t => t.AreaId == areaid).ToListAsync(); return Json(teams.Select(t => new SelectListItem { Text = t.TeamName, Value = t.TeamId.ToString() })); } // Error方法代码保持不变 } }
4. 视图和JS代码保持不变(已修正选择器后)
EF Core会自动处理数据库连接和查询逻辑,大幅减少手动出错的概率,代码可读性和可维护性更强。
内容的提问来源于stack exchange,提问作者dori2o
相关产品推荐
相关产品推荐

