You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 21:37:55