• 快读《ASP.NET Core技术内幕与项目实战》WebApi3.1:WebApi最佳实践


    本节内容,涉及到6.1-6.6(P155-182),以WebApi说明为主。主要NuGet包:无

     

    一、创建WebApi的最佳实践,综合了RPC和Restful两种风格的特点

    复制代码
     1 //定义Person类和ErrorInfo类
     2 public record Person(int Id, string Name, int Age);
     3 public record ErrorInfo(int Code, string? Message);
     4 
     5 
     6 //定义控制器和一个Get方法
     7 [ApiController]
     8 [Route("api/[controller]/[action]")] 
     9 public class TestController : ControllerBase
    10 {
    11     //模拟一个persons数据集合
    12     private List persons = new List();
    13     public TestController()
    14     {
    15         var p1 = new Person(1, "ZS", 25);
    16         var p2 = new Person(2, "LS", 18);
    17         var p3 = new Person(3, "WU", 35);
    18         var p4 = new Person(4, "ZL", 46);
    19         persons.Add(p1);
    20         persons.Add(p2);
    21         persons.Add(p1);
    22         persons.Add(p1);
    23 
    24     }
    25 
    26     [HttpGet("{id}")]
    27     public ActionResult GetPersonById(int id)
    28     {
    29         if (id < 1)
    30         {
    31             return BadRequest(new ErrorInfo(1, "id必须是正数"));
    32         }
    33         else if(id > 4)
    34         {
    35             return NotFound(new ErrorInfo(2, "查无此人"));
    36         }
    37         else
    38         {
    39             return persons.FirstOrDefault(p => p.Id == id);
    40         }
    41     }
    42 }
    复制代码

    代码解读:

    8行:统一设置控制器类的路径为[controller]/[action],控制器+方法名,前缀api可省略。这个方式倾向于RPC风格,可以直接知道API的意图

    9行:因为不需要MVC中的视图功能,所以WebApi的控制器继承ControllerBase即可,ControllerBase中定义了Response、Request、HttpContext等属性成员来获取请求和响应信息,以及BadRequest、NotFound、OK等方法来快速设置响应报文。

    26行:所有方法,都须加上Http方法的Attribute,主要有[HttpGet]、[HttpPost]、[HttpPut]、[HttpDelete],分别进行查询、新增、更新、删除操作。这不仅有利于明确操作方法的请求类型,也有利于使用Swagger+OpenApi来生成文档。使用Swagger时,如果没有标注,会报错,如果确定这个方法不生成Api,可以标注[ApiExplorerSettings(IgnoreApi = true)]

    27行:返回值如果是普通类型,直接返回即可,会自动序列化为JSON格式,但如果返回值为复杂类型,需要使用ActionResult泛型类型来包装

    31,35行:使用BadRequest、NotFound、Ok等方法,快速设置响应数据,可以和ActionResult很好的结合使用。其中BadRequest的响应状态码为400,NotFound为404,Ok为200。同时,方法参加为一个自定义ErrorInfo对象,包括错误码和错误信息两个属性,进一步说明具体的错误信息。方法会自动将ErrorInfo对象序列化为JSON对象

    39行:直接返回对象,因为方法设置了返回值为ActionResult,自动将复杂对象序列化为JSON对象。这里严谨一点,应该判断一下是否为null

    补充说明:

    ①HTTP的四个常用请求谓词的特征:GET/Put/DELETE是幂等操作,网关或网络请求组件会对失败请求自动重试;POST是非幂等的,需要注意重复提交的情况;GET请求的响应可以被缓存,而其它请求不能被缓存;GET和DELETE不支持请求体传参,POST和PUT支持

    ②HTTP的常用状态码:401,需要身份认证的但是没有提供;403,需要权限的但没有权限;404,请求的资源不存在;400,请求参数错误或其它业务错误;200,请求处理成功

    ③如果方法中调用了异步方法,则返回值为async Task>

     

    二、Api方法参数的最佳实践

    1、通过URL

     

    复制代码
    //通过HttpGet的参数设置请求路径,其中{}内的,为路径参数
    //如果方法参数的名称和{}内的不一样,则参数使用[FromRoute]指定
    //下例中,如果请求参数schoolName为aaa,classNo为bbb,则请求路径为api/Test/GetAll/school/aaa/class/bbb
    [HttpGet("school/{schoolName}/class/{classNo}")]
    public ActionResult GetAll(string schoolName, [FromRoute(Name = "classNo")] string classNum){}
    复制代码

     

     

    2、通过QueryString

    复制代码
    //从Query中获取实参时,就不需要在HttpGet中设置路径
    //如果请求参数名称和方法行参名称不同,则要指定[FromQuery]的Name属性
    //下例中,如果请求参数schoolName为aaa,classNo为bbb,则请求地址为api/Test/GetAll?schoolName=aaa&classNo=bbb
    [HttpGet]
    public ActionResult GetAll(string schoolName, [FromQuery(Name = "classNo")]string classNum){}
    复制代码

     

    3、通过请求体

    复制代码
    //方法参数为复杂类型时,自动序列化为JSON,通过请求体发送
    //参数中可加、可不加[FromBody]
    //请求地址为api/Test/AddNew
    [HttpPost]
    public ActionResult AddNew(Student studentDto)
    {
        persons.Add(studentDto);
        return Ok(studentDto);
    }
    复制代码

     

    4、除了FromRoute、FromQuery、FromBody之外,还有FromForm、FromHeader等

     

    5、传递参数最佳实践:

    ①GET和DELETE请求,参数使用QueryString

    ②POST请求,参数使用请求体

    ③PUT请求,定位参数,如Id,使用QueryString;DTO参数,使用请求体

    ④GET请求,如果参数内容超过URL长度限制,则把请求改为PUT,并通过请求体来传递参数

    ⑤Restful风格,要求路径参数用于定位资源,Query参数用于传递额外参数,但使用Query更符合中文习惯,所以URL还是比较少使用

    ⑥注意:请求报文头的Content-Type要设置为application/JSON

     

       

    特别说明:
    1、本系列内容主要基于杨中科老师的书籍《ASP.NET Core技术内幕与项目实战》及配套的B站视频视频教程,同时会增加极少部分的小知识点
    2、本系列教程主要目的是提炼知识点,追求快准狠,以求快速复习,如果说书籍学习的效率是视频的2倍,那么“简读系列”应该做到再快3-5倍

     

  • 相关阅读:
    渗透测试怎么入门?(超详细解读)
    ws升级为wss
    iPhone15系类LDR6020P 超简外围手机转接器/拓展坞方案
    IMX6ULL学习笔记(2)——通过SD卡烧录镜像
    【运维】docker如何删除所有容器
    云HIS 医院综合运营管理系统源码
    这款吊打Chrome、Edge的浏览器,时隔573天再度更新
    Blender程序化设置材质【Python】
    GDB用法(三)
    vscode连接wsl-ubuntu失败
  • 原文地址:https://www.cnblogs.com/functionMC/p/16840281.html