ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2022-06-16 19:34:58  阅读:164  来源: 互联网

标签:CORE ASP name 读书笔记 更新 new PUT path op


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

标签:CORE,ASP,name,读书笔记,更新,new,PUT,path,op
来源: https://www.cnblogs.com/huangwenhao1024/p/16383182.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有