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

如何在MediatR的Unit类型场景下处理删除项的结果判断

解决MediatR Unit返回值无法判断数据不存在的问题

你遇到的编译器报错,根源是Unit是值类型(struct),值类型永远不会等于null,所以result == null这个判断逻辑永远不成立,编译器直接提示错误。要实现“数据不存在时返回失败状态”的需求,有两种常用解决思路:

方案一:自定义返回类型替换Unit

直接让MediatR命令返回你的RowResponse<ItemDto>对象,这样Handler可以把处理结果(成功/失败、错误信息)直接封装进去,Controller无需判断null,直接使用返回对象的状态。

修改ItemDeleteHandler代码:

  1. 让Command实现IRequest<RowResponse<ItemDto>>,指定返回类型:
public class Command : IRequest<RowResponse<ItemDto>>
{
    public int Id { get; set; }
}
  1. 修改CommandHandler的泛型参数,返回RowResponse<ItemDto>:
public class CommandHandler : IRequestHandler<Command, RowResponse<ItemDto>>
{
    private readonly FinContext _db;
    public CommandHandler(FinContext db) => _db = db;

    public async Task<RowResponse<ItemDto>> Handle(Command req, CancellationToken cancellationToken)
    {
        var response = new RowResponse<ItemDto>();
        var itemData = await _db.Item.FindAsync(req.Id);

        if (itemData == null)
        {
            response.IsOk = false;
            response.ErrorMessage = "Data not found";
            return response;
        }
        
        _db.Item.Remove(itemData);
        await _db.SaveChangesAsync(cancellationToken);
        
        response.IsOk = true;
        response.ErrorMessage = $"Item with id {req.Id} has been deleted";
        return response;
    }
}

修改ItemController代码:

直接返回Handler返回的响应对象即可:

[HttpDelete("{id}")]
public async Task<ActionResult> Delete(int id)
{
    var result = await _mediator.Send(new ItemDeleteHandler.Command { Id = id });
    return Ok(result);
}

方案二:抛出异常+捕获处理(符合REST规范)

如果希望遵循RESTful设计,数据不存在时返回404 Not Found状态码,可在Handler中抛出异常,然后在Controller或全局异常过滤器中捕获处理。

修改ItemDeleteHandler的Handle方法:

public async Task<Unit> Handle(Command req, CancellationToken cancellationToken)
{
    var itemData = await _db.Item.FindAsync(req.Id);
    if (itemData == null)
    {
        // 抛出KeyNotFoundException或自定义异常
        throw new KeyNotFoundException("Data not found");
    }
    
    _db.Item.Remove(itemData);
    await _db.SaveChangesAsync(cancellationToken);
    return Unit.Value;
}

修改ItemController代码:

[HttpDelete("{id}")]
public async Task<ActionResult> Delete(int id)
{
    var response = new RowResponse<ItemDto>();
    try
    {
        await _mediator.Send(new ItemDeleteHandler.Command { Id = id });
        response.IsOk = true;
        response.ErrorMessage = $"item with id {id} was deleted";
        return Ok(response);
    }
    catch (KeyNotFoundException ex)
    {
        response.IsOk = false;
        response.ErrorMessage = ex.Message;
        // 返回404状态码,更符合REST规范
        return NotFound(response);
    }
}

方案对比

  • 方案一:适合需要统一返回格式的场景,前端只需解析响应体的IsOk字段即可判断结果。
  • 方案二:符合HTTP状态码语义,前端可根据状态码快速区分成功/失败场景,推荐用于REST API开发。

内容的提问来源于stack exchange,提问作者reza irawan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 09:01:22