API展示课程用户时遇‘对象引用未设置实例’错误求助
问题排查与解决方案
错误根源分析
- 仓库方法逻辑错位:你的
GetUsers方法命名与实际功能不符,它返回的是匹配CourseId的Course集合,而非该课程下的User集合,直接导致后续控制器逻辑偏离需求。 - 无效的null判断:
_db.Course.Where(...).ToList()永远不会返回null,只会返回空集合,所以控制器里的objList == null判断完全无效。当没有找到对应课程时,objList是空集合,foreach循环不会执行,最终返回空列表;如果找到课程,若Course的Users导航属性为null(比如EF Core未正确加载关联数据),会引发映射时的空引用错误。 - DTO语法错误:
ViewCourseDetailsDTO类中CourseTitle属性末尾多了一个分号,这会导致编译警告,也可能间接引发运行时问题。 - 控制器逻辑不符合需求:你需要展示某一课程下的所有用户,但当前逻辑是将Course集合映射为包含Users的DTO集合,而非直接返回目标数据。
解决方案
1. 修正仓库方法
根据实际需求二选一:
- 需求A:返回课程详情+关联用户列表
public Course GetCourseWithUsers(int courseId) { // 使用FirstOrDefault返回单个课程对象,找不到则返回null return _db.Course.Include(c => c.Users) .FirstOrDefault(c => c.CourseId == courseId); } - 需求B:仅返回该课程下的用户列表
public ICollection<User> GetUsersByCourseId(int courseId) { // 通过SelectMany直接提取课程下的所有用户 return _db.Course.Where(c => c.CourseId == courseId) .SelectMany(c => c.Users) .ToList(); }
2. 修正控制器逻辑
对应上述两种需求:
- 需求A的控制器代码
var course = _courseRepo.GetCourseWithUsers(CourseId); if (course == null) { return NotFound(); } // 直接映射单个Course对象到DTO var dto = _mapper.Map<ViewCourseDetailsDTO>(course); return Ok(dto); - 需求B的控制器代码
var users = _courseRepo.GetUsersByCourseId(CourseId); if (!users.Any()) { return NotFound(); } // 映射用户集合到UserDTO列表 var userDtos = _mapper.Map<List<UserDTO>>(users); return Ok(userDtos);
3. 修复DTO语法错误
去掉CourseTitle属性末尾的多余分号:
public class ViewCourseDetailsDTO { public int CourseId { get; set; } public string CourseTitle { get; set; } public ICollection<UserDTO>? Users { get; set; } = new List<UserDTO>(); }
4. 验证AutoMapper配置
确保已正确配置映射规则:
// 在AutoMapper配置文件中添加 CreateMap<Course, ViewCourseDetailsDTO>(); CreateMap<User, UserDTO>();
关于UserDTO的疑问
不需要拆分UserDTO,当前的UserDTO结构完全满足需求,问题根源不在DTO的结构上,而是仓库方法和控制器逻辑的错误。
内容的提问来源于stack exchange,提问作者Mnda90
相关产品推荐
相关产品推荐

