在C# Executor文件新增校验时遭遇空引用异常求助
空引用异常排查与修复:C# Executor新增校验逻辑报错
我是C#新手,正在现有Executor文件中新增一项校验逻辑。添加新DTO后,校验时出现空对象,引发500错误,异常信息为:
Exception Message: Object reference not set to an instance of an object
校验代码如下:
if(currentDto.InvoiceId.HasValue && !userRoleDto.Role.Contains("Admin")){ throw new BadRequestException("Only an admin can edit an invoiced work order"); }
我期望userRoleDto.Role为“Admin”,逻辑看似正确,但不确定能否在WorkOrderDTO所在代码块中引入该DTO,因此参照currentDto的方式用var初始化了userRoleDto,仍出现问题。相关代码如下:
namespace Domain.Data.WorkOrder.Commands; public abstract class WorkOrderServiceUpdateExecutor<TCommand, TWorkOrder> : ICommandExecutor<DeltaWrapper<TCommand>> where TWorkOrder : Models.WorkOrder where TCommand : UpdateBasicWorkOrder { private readonly IWorkOrderService _service; private readonly IUserService _userService; //ADDING USERSERVICE private readonly IPatcher _patcher; private readonly IMapper _mapper; protected WorkOrderServiceUpdateExecutor( IWorkOrderService service, IPatcher patcher, IMapper mapper) { _service = service; _patcher = patcher; _mapper = mapper; } public async Task ExecuteAsync(DeltaWrapper<TCommand> deltaWrapper) { var currentDto = await _service.GetFirstAsync(deltaWrapper.FilterSet ?? new FilterSet() { [nameof(BaseEntity.OrganizationId)] = new FilterValue(deltaWrapper.OrganizationId), [nameof(BaseEntity.Id)] = new FilterValue(deltaWrapper.Id) }); var userRoleDto = await _userService.GetFirstAsync(deltaWrapper.FilterSet ?? new FilterSet() { [nameof(BaseEntity.OrganizationId)] = new FilterValue(deltaWrapper.OrganizationId), [nameof(BaseEntity.Id)] = new FilterValue(deltaWrapper.Id) }); if(currentDto==null) throw new NotFoundException("not found"); //if(currentDto.InvoiceId.HasValue && !userRoleDto.Role.Contains("Admin")){ //throw new BadRequestException("Only an admin can edit an invoiced work //order"); } _patcher.Patch(currentDto, deltaWrapper); await _service.UpdateAsync(currentDto); var command = deltaWrapper.Command.OriginalCommand; } }
问题根源与修复步骤
1. 构造函数未注入IUserService
你已经声明了_userService私有字段,但构造函数里没有添加该参数并赋值,导致_userService为null,调用GetFirstAsync时直接触发空引用异常。
修复后的构造函数:
protected WorkOrderServiceUpdateExecutor( IWorkOrderService service, IUserService userService, IPatcher patcher, IMapper mapper) { _service = service; _userService = userService; _patcher = patcher; _mapper = mapper; }
2. 用户查询过滤条件错误
你用工单ID(deltaWrapper.Id)去查询用户,这是错误的——工单ID和当前操作的用户ID不是同一个值,导致userRoleDto查询结果为null,后续访问userRoleDto.Role时抛出异常。
需要从deltaWrapper或请求上下文中获取当前登录用户的ID,替换过滤条件。假设deltaWrapper包含当前用户ID的字段UserId,修改代码如下:
var userRoleDto = await _userService.GetFirstAsync(new FilterSet() { [nameof(BaseEntity.OrganizationId)] = new FilterValue(deltaWrapper.OrganizationId), [nameof(UserEntity.Id)] = new FilterValue(deltaWrapper.UserId) });
3. 必须检查userRoleDto是否为null
即使修复了过滤条件,仍可能存在查询不到用户的情况,必须先判断userRoleDto是否为null,再访问其属性:
if(currentDto.InvoiceId.HasValue) { if(userRoleDto == null) { throw new UnauthorizedAccessException("用户不存在"); } if(!userRoleDto.Role.Contains("Admin")) { throw new BadRequestException("Only an admin can edit an invoiced work order"); } }
4. 可选:防范Role字段为空
如果userRoleDto.Role可能为null,需要额外判断,避免调用Contains方法时触发异常:
if(currentDto.InvoiceId.HasValue && userRoleDto != null) { if(string.IsNullOrEmpty(userRoleDto.Role) || !userRoleDto.Role.Contains("Admin")) { throw new BadRequestException("Only an admin can edit an invoiced work order"); } }
内容的提问来源于stack exchange,提问作者Jamie Garcia
相关产品推荐
相关产品推荐

