Ultimate ASP.NET CORE 6.0 Web API --- 读书笔记(10 - 12)

2022/6/17 1:20:06

本文主要是介绍Ultimate ASP.NET CORE 6.0 Web API --- 读书笔记(10 - 12),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

10 Working With DELETE Requests

本文内容来自书籍: Marinko Spasojevic - Ultimate ASP.NET Core Web API - From Zero To Six-Figure Backend Developer (2nd edition)

11 Working With PUT Requests

需要给PUT API提供一个新的DTO,虽然内容是一样的,不过还是需要区分开比较好,这个原因会在模型验证的章节说明

两种情况的更新

  • 有关联的更新,有关联指的是查询数据和更新数据是在同一个Context中,因此,如果查询的数据(已经被跟踪)被修改了,那么状态会变成Modified,然后直接调用Save方法,就会产生Update SQL
  • 无关联的更新,指的是查询和更新的操作不在同一个Context中进行,也就是说你需要更新的这个实体,是没有被当前的Context所跟踪的,而且这个实体是具有Id的,这样的没有被跟踪的实体,需要先是将它加入Context或者说被跟踪,然后再设置状态为Modified,然后Save的时候,就会有Update SQL,不过有一个问题,就是,即使只是更新了其中一个字段,也会有全字段的更新

12 Working With PATCH Requests

PUT 负责全更新
PATCH 部分更新

但是这个不是它们两者之间的唯一区别,请求体也不一样

  • PATCH的请求体是:[FromBody]JsonPatchDocument<Company>,格式是
[
    {
        "op": "replace",
        "path": "/name",
        "value": "new name"
    },
    {
        "op": "remove",
        "path": "/name"
    }
]

一共有六种不同的操作

// 赋值
{
    "op": "add",
    "path": "/name",
    "value": "new name"
},
// 赋值
{
    "op": "replace",
    "path": "/name",
    "value": "new name"
},
// 赋值(默认值)
{
    "op": "remove",
    "path": "/name"
},
// 将from的值赋给path
{
    "op": "copy",
    "from": "/name",
    "path": "/title"
},
// 将from的值赋给path
{
    "op": "move",
    "from": "/name",
    "path": "/title"
},
// 测试特定字段是否有特定值
{
    "op": "test",
    "path": "/name",
    "value": "new name"
}
  • PUT的请求体是:[FromBody]Company

media type也不一样

  • PATCH的是:application/json-patch+json,虽然直接用application/json也是能用的,不过建议是用这种
  • PUT的是:application/json

那么在ASP.NET Core中,需要安装相应的包实现
在主项目中,安装Microsoft.AspNetCore.Mvc.NewtonsoftJson,用以支持请求体转换成PatchDocument

Presentation中安装Microsoft.AspNetCore.JsonPatch,用以支持JsonPatchDocument在控制器中使用

在主项目的配置中,如果直接使用AddNewtonsoftJson,那么它会替换System.Text.Json formatters,然后是全局替换,所有的JSON序列化工作都被转移了,但是作者不希望这样做,只希望在局部使用这个JSON包,所以在Program.cs

// 添加一个本地方法
NewtonsoftJsonPatchInputFormatter GetJsonPatchInputFormatter() =>
    new ServiceCollection()
        .AddLogging()
        .AddMvc()
        .AddNewtonsoftJson()
        .Services.BuildServiceProvider()
        .GetRequiredService<IOptions<MvcOptions>>().Value.InputFormatters
        .OfType<NewtonsoftJsonPatchInputFormatter>()
        .First();

builder.Services.AddControllers(config =>
    {
        config.RespectBrowserAcceptHeader = true;
        config.ReturnHttpNotAcceptable = true;
        config.InputFormatters.Insert(0, GetJsonPatchInputFormatter());
    })
    .AddXmlDataContractSerializerFormatters()
    .AddCustomCsvFormatter()
    .AddApplicationPart(typeof(AssemblyReference).Assembly);

自动映射,可以正向和反向一起,这样就不用重复写

CreateMap<EmployeeForUpdateDto, Employee>().ReverseMap();
[HttpPatch("{id:guid}")]
    public IActionResult PartiallyUpdateEmployeeForCompany(Guid companyId, Guid id, 
        [FromBody] JsonPatchDocument<EmployeeForUpdateDto>? patchDoc)
    {
        if (patchDoc is null)
            return BadRequest("patchDoc object sent from client is null.");
        
        var result = _service.EmployeeService.GetEmployeeForPatch(companyId, id,
            compTrackChanges: false,
            empTrackChanges: true);
            
        patchDoc.ApplyTo(result.employeeToPatch);
        
        _service.EmployeeService.SaveChangesForPatch(result.employeeToPatch,
            result.employeeEntity);
        
        return NoContent();
    }

然后可以看到,在请求体的接受上,与PUT方法是不一样的,然后处理方式是先查询出原有的对象,然后将JSONdoc转换为DTO,然后调用Save方法,内部会将DTO转换为Entity,由于前面查询Entity是有跟踪的,所以在修改了Entity之后,模型状态就是Modified了,直接保存就会有Update SQL



这篇关于Ultimate ASP.NET CORE 6.0 Web API --- 读书笔记(10 - 12)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程