如何在MediatR的Unit类型场景下处理删除项的结果判断
解决MediatR Unit返回值无法判断数据不存在的问题
你遇到的编译器报错,根源是Unit是值类型(struct),值类型永远不会等于null,所以result == null这个判断逻辑永远不成立,编译器直接提示错误。要实现“数据不存在时返回失败状态”的需求,有两种常用解决思路:
方案一:自定义返回类型替换Unit
直接让MediatR命令返回你的RowResponse<ItemDto>对象,这样Handler可以把处理结果(成功/失败、错误信息)直接封装进去,Controller无需判断null,直接使用返回对象的状态。
修改ItemDeleteHandler代码:
- 让
Command实现IRequest<RowResponse<ItemDto>>,指定返回类型:
public class Command : IRequest<RowResponse<ItemDto>> { public int Id { get; set; } }
- 修改
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
相关产品推荐
相关产品推荐

