【发布时间】:2021-06-18 21:31:32
【问题描述】:
我使用 PUT/POST 来更新我正在使用的应用程序,到目前为止这一直很简单。现在我正在开发一个 API,它应该公开一种更新数据库中数据的方法,我最初的想法是我可以替换该行(或部分替换它)。由于具有不同数据知识的不同应用程序需要更新,我认为使用 PATCH 操作而不是 PUT 可能是个好主意。
我可以找到一些在控制器中实现更新的玩具示例,我对此并不感兴趣。
我使用与 jasontaylordev 的 Clean architecture 项目中相同的模式(CQRS w. Mediatr),所以我将在我的示例中使用它。
我有两个问题。
-
我不喜欢
JsonPatchDocument对象应该到达我的处理程序,但我不知道如何避免这种情况。从控制器访问数据库不是一种选择。那么还有其他选择吗? (n.b. Automapper 或类似的动态映射库在我正在处理的项目中都不是一个选项) -
如何从客户端应用程序(所有 dotnet 核心项目)构建 JsonPatch 对象。我认为如果我可以在具有两个属性
Title和Note以及Title="test"和Note=null的应用程序中拥有一个DTO,那么它应该替换标题并删除注释。我能以简单的方式映射到(奇怪的)补丁对象吗?[HttpPatch("{id}")] public async Task<ActionResult> Update(int id, UpdateTodoItemCommand command) { if (id != command.Id) { return BadRequest(); } await Mediator.Send(command); return NoContent(); } public class UpdateTodoItemCommand : IRequest { public int Id { get; set; } public JsonPatchDocument<TodoItemDto> Todo { get; set; } } public class TodoItemDto { public string Title { get; set; } public string Note { get; set; } } public class UpdateTodoItemCommandHandler : IRequestHandler<UpdateTodoItemCommand> { private readonly IApplicationDbContext _context; public UpdateTodoItemCommandHandler(IApplicationDbContext context) { _context = context; } public async Task<Unit> Handle(UpdateTodoItemCommand request, CancellationToken cancellationToken) { var entity = await _context.TodoItems.FindAsync(request.Id); if (entity == null) { throw new NotFoundException(nameof(TodoItem), request.Id); } var todoItemDto = new TodoItemDto(); todoItemDto.Title = entity.Title; todoItemDto.Note = entity.Note: todoItemDto.Todo.ApplyTo(request.Todo); entity.Title = todoItemDto.Title; entity.Note = todoItemDto.Note; await _context.SaveChangesAsync(cancellationToken); return Unit.Value; } }
【问题讨论】:
-
通过 JsonPatch 对象是什么意思?您是指 ASP.NET Core 中的 JsonPatchDocument
吗? -
是的,我的意思是 JsonPatchDocument
标签: .net .net-core patch mediatr