ASP.NET Core 6使用SelectList构建下拉列表遇错误或无数据
问题分析与修复方案
你的代码存在多个拼写错误、数据源逻辑错误以及服务缺失问题,导致下拉框无数据或运行报错,以下是具体修复步骤:
1. 补充视图模型的分类数据源
当前视图模型没有存储事件分类列表,无法为下拉框提供选项数据,修改视图模型:
public class EventsViewModel { public List<Events> events { get; set; } public Events NewEvents { get; set; } // 新增分类列表字段,用于下拉框数据源 public List<EventsCategories> EventsCategoriesList { get; set; } }
2. 实现事件分类的服务逻辑
需要为EventsCategories实现对应的服务类,才能获取分类数据:
public class ServicesEventsCategories : IServicesRepository<EventsCategories> { private readonly ProjectDBContext _context; public ServicesEventsCategories(ProjectDBContext context) { _context = context; } public bool Delete(Guid Id) { try { var category = _context.eventsCategories.Find(Id); if (category != null) { _context.eventsCategories.Remove(category); _context.SaveChanges(); return true; } return false; } catch (Exception) { return false; } } public EventsCategories FindBy(Guid Id) { try { return _context.eventsCategories.FirstOrDefault(x => x.Id.Equals(Id)); } catch (Exception) { return null; } } public List<EventsCategories> GetAll() { try { return _context.eventsCategories.OrderBy(x => x.Name).ToList(); } catch (Exception) { return null; } } public bool Save(EventsCategories model) { try { var result = FindBy(model.Id); if (result == null) { model.Id = Guid.NewGuid(); _context.eventsCategories.Add(model); } else { result.Name = model.Name; _context.eventsCategories.Update(result); } _context.SaveChanges(); return true; } catch (Exception) { return false; } } }
3. 修正控制器逻辑
- 注入分类服务,传递分类数据到视图
- 修正变量名错误(
_servicesEvents改为servicesEvents或统一命名) - 修复新增时名称重复检查的逻辑(原代码用
FindBy传字符串类型不匹配)
public class EventsController : Controller { private readonly IServicesRepository<Events> _servicesEvents; private readonly IServicesRepository<EventsCategories> _servicesCategories; public EventsController(IServicesRepository<Events> servicesEvents, IServicesRepository<EventsCategories> servicesCategories) { _servicesEvents = servicesEvents; _servicesCategories = servicesCategories; } public IActionResult Events() { return View(new EventsViewModel { events = _servicesEvents.GetAll(), NewEvents = new Events(), // 传递分类列表到视图 EventsCategoriesList = _servicesCategories.GetAll() }); } [HttpPost] [AutoValidateAntiforgeryToken] public IActionResult Save(EventsViewModel model) { if (ModelState.IsValid) { // 检查名称是否重复(新增时排除自身) bool isNameDuplicate = model.NewEvents.Id == Guid.Empty ? _servicesEvents.GetAll().Any(e => e.Name.Equals(model.NewEvents.Name, StringComparison.OrdinalIgnoreCase)) : _servicesEvents.GetAll().Any(e => e.Name.Equals(model.NewEvents.Name, StringComparison.OrdinalIgnoreCase) && e.Id != model.NewEvents.Id); if (isNameDuplicate) { // 替换为你的Session提示逻辑,比如TempData["Error"] = "事件名称已存在"; } else { bool saveResult = _servicesEvents.Save(model.NewEvents); // 替换为你的Session提示逻辑 } } // 验证失败时重新加载分类数据,避免下拉框为空 model.EventsCategoriesList = _servicesCategories.GetAll(); return View(nameof(Events), model); } }
4. 修正视图的拼写与数据源错误
- 修正字段名拼写错误(
EventCategories→EventsCategories,CategoryId→EventsCategoriesId) - 下拉框改为使用视图模型的分类列表作为数据源
- 修复未闭合的标签
<!-- 表格部分修正 --> <table> <thead> <tr> <td>Name</td> <td>Category Name</td> </tr> </thead> <tbody> @foreach (var item in Model.events) { <tr> <td>@item.Name</td> <td>@item.EventsCategories?.Name</td> <!-- 用?.避免空引用异常 --> </tr> } </tbody> </table> <!-- 表单部分修正 --> <form asp-action="Save" asp-controller="Events" method="post"> <div class="form-group"> <label asp-for="NewEvents.Name" class="control-label">Name</label> <input type="text" class="form-control" asp-for="NewEvents.Name" /> <span asp-validation-for="NewEvents.Name" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="NewEvents.EventsCategoriesId" class="control-label">Category</label> <select class="custom-select-sm" asp-for="NewEvents.EventsCategoriesId" asp-items="@(new SelectList(Model.EventsCategoriesList,"Id","Name"))"> <option value="">请选择分类</option> </select> <span asp-validation-for="NewEvents.EventsCategoriesId" class="text-danger"></span> </div> <!-- 隐藏字段传递事件ID,用于更新逻辑 --> <input type="hidden" asp-for="NewEvents.Id" /> <button type="submit" class="btn btn-primary">保存</button> </form>
5. 补充事件服务的Delete方法实现
原ServicesEvents中的Delete方法未实现,会导致编译错误:
public bool Delete(Guid Id) { try { var eventItem = _context.events.Find(Id); if (eventItem != null) { _context.events.Remove(eventItem); _context.SaveChanges(); return true; } return false; } catch (Exception) { return false; } }
6. 注册服务
在Program.cs(.NET 6+)或Startup.cs中注册新增的分类服务:
builder.Services.AddScoped<IServicesRepository<Events>, ServicesEvents>(); builder.Services.AddScoped<IServicesRepository<EventsCategories>, ServicesEventsCategories>();
内容的提问来源于stack exchange,提问作者Hazem Ahmed
相关产品推荐
相关产品推荐

