这里介绍在ASP.NET Core中使用Web API创建 RESTful 服务,本文使用VSCode + NET Core3.0

  1. 创建简单Rest API
  2. 格式化输出
  3. JSON Patch请求
  4. Open API(Swagger)集成

创建简单Rest API

在终端输入

dotnet new webapi -n WebAPI

1. 创建Order模型,然后初始化数据

public class OrderStore
{
public List<Order> Orders { get; } = new List<Order>(); public OrderStore()
{
var random = new Random();
foreach (var item in Enumerable.Range(, ))
{
Orders.Add(new Order
{
Id = item,
OrderNo = DateTime.Now.AddSeconds(random.Next(, )).AddMilliseconds(random.Next(, )).Ticks.ToString(),
Quantity = random.Next(, ),
Amount = Math.Round(((decimal)random.Next(, ) / random.Next(, )), )
});
}
}
}

2. 简单REST API接口

/// <summary>
/// 订单模块
/// </summary>
[ApiController]
[Route("[controller]")]
[FormatFilter]
public class OrderController : ControllerBase
{ readonly Models.OrderStore _orderStore = null;
public OrderController(Models.OrderStore orderStore)
{
_orderStore = orderStore;
} /// <summary>
/// 查询所有订单
/// </summary>
[HttpGet]
public ActionResult<List<Models.Order>> GetAll() => _orderStore.Orders; /// <summary>
/// 获取订单
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet("{id:int}.{format?}")]
public ActionResult<Models.Order> GetById(int id)
{
var order = _orderStore.Orders.FirstOrDefault(m => m.Id == id); if (order == null)
{
return NotFound();
} return order;
} /// <summary>
/// 创建订单
/// </summary>
/// <param name="order"></param>
/// <returns>成功返回订单Id,失败返回-1</returns>
[HttpPost]
public ActionResult<int> Create(Models.Order order)
{
if (_orderStore.Orders.Any(m => m.OrderNo == order.OrderNo))
{
return -;
} order.Id = _orderStore.Orders.Max(m => m.Id) + ;
_orderStore.Orders.Add(order); return order.Id;
} /// <summary>
/// 更新订单
/// </summary>
/// <returns></returns>
[HttpPut]
public ActionResult<bool> Update(Models.Order model)
{
Console.WriteLine($"OrderNo:{model.OrderNo}");
var order = _orderStore.Orders.FirstOrDefault(m => m.OrderNo == model.OrderNo); if (order == null)
{
return NotFound();
} order.Amount = model.Amount;
order.Quantity = model.Quantity; return true;
} /// <summary>
/// 更新订单指定信息
/// </summary>
/// <remarks>
/// Sample request:
///
/// PATCH /Order/{orderNo}
/// [
/// {
/// "op": "test",
/// "path": "/quantity",
/// "value": "2"
/// },
/// {
/// "op": "test",
/// "path": "/amount",
/// "value": "38.28"
/// },
/// {
/// "op": "add",
/// "path": "/isComplete",
/// "value": "true"
/// },
/// ]
/// </remarks>
/// <returns>返回是否成功</returns>
/// <response code="200">提交成功</response>
/// <response code="400">提交参数异常</response>
/// <response code="404">订单号不存在</response>
[HttpPatch("{orderNo:length(18)}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<bool> Update([FromBody] JsonPatchDocument<Models.Order> patchDoc, [FromRoute] string orderNo)
{
var order = _orderStore.Orders.FirstOrDefault(m => m.OrderNo == orderNo); if (order == null)
{
return NotFound();
} patchDoc.ApplyTo(order, ModelState); if (!ModelState.IsValid)
{
return BadRequest(ModelState);
} return Ok(true);
}
}

3. 推荐一个VS Code插件(REST Client)测试接口,官方介绍

@baseUrl = https://localhost:5001

###
GET {{baseUrl}}/Order HTTP/1.1 ###
# @name order
POST {{baseUrl}}/Order HTTP/1.1
Accept: application/json
Content-Type: application/json {
"OrderNo": "",
"Quantity": ,
"Amount": 38.28
} ### @orderId = {{order.response.body.*}}
GET {{baseUrl}}/Order/{{orderId}}.json HTTP/1.1 ###
GET {{baseUrl}}/Order/{{orderId}}.xml HTTP/1.1
###
GET {{baseUrl}}/Order/{{orderId}} HTTP/1.1
### PUT {{baseUrl}}/Order HTTP/1.1
Content-Type: application/json
Accept: application/json {
"Id": ,
"OrderNo": "",
"Quantity": ,
"Amount": 38.28
} ### GET {{baseUrl}}/Order/ ### PATCH {{baseUrl}}/Order/ HTTP/1.1
Accept: application/json
Content-Type: application/json [
{
"op": "test",
"path": "/quantity",
"value": ""
},
{
"op": "test",
"path": "/amount",
"value": "38.28"
},
{
"op": "add",
"path": "/isComplete",
"value": "true"
},
] Sample request: PATCH /Order/{orderNo} [
{
"op": "test",
"path": "/quantity",
"value": ""
},
{
"op": "test",
"path": "/amount",
"value": "38.28"
},
{
"op": "add",
"path": "/isComplete",
"value": "true"
},
]

简单介绍一下,

文件后缀是http 或 rest

定义全局变量:@baseUrl = https://localhost:5001   ,注意链接不加引号

### 分割多个请求

POST/PUT 请求紧跟Head请求信息,换行加上请求内容

Ctrl + Alt + R 快捷键 / 点Send Request发起请求
 

格式化输出

Api接口通常会是不同客户端调用,这样会有可能出现需要不同响应格式,例如常用的Json,XML。
ASPNET Core 默认情况下是忽略 Accept 标头,JSON格式返回
一、支持XML格式
1. 添加xml格式化
services.AddControllers(options =>
{
options.RespectBrowserAcceptHeader = true; //接受浏览器标头
})
.AddXmlSerializerFormatters(); //添加XMl格式化
}

2. 请求是添加标头

@orderId = {{order.response.body.*}}
GET {{baseUrl}}/Order/{{orderId}} HTTP/1.1
Accept: text/xml

若不添加标头,默认使用JSON格式输出

二、URL格式映射

1. 添加[FormatFilter]过滤器,它会检查路由中格式是否存在,并且使用相应的格式化程序输出

2. 路由规则添加{format?}

[HttpGet("{id:int}.{format?}")]
public ActionResult<Models.Order> GetById(int id)
{
var order = _orderStore.Orders.FirstOrDefault(m => m.Id == id); if (order == null)
{
return NotFound();
} return order;
}
Url 响应
GET {{baseUrl}}/Order/{{orderId}} HTTP/1.1
JSON(若配置格式化输出)
GET {{baseUrl}}/Order/{{orderId}}.xml
XML(若配置格式化输出)
GET {{baseUrl}}/Order/{{orderId}}.json
JSON(若配置格式化输出)
 
三、添加基于 Newtonsoft.Json 的 JSON 格式支持
 
在ASPNET Core 3.0开始,不再使用Newtonsoft.Json格式化JSON,而是使用System.Text.Json格式化,我们可以替换成Newtonsoft.Json
 
1. 添加包
dotnet add package Microsoft.AspNetCore.Mvc.NewtonsoftJson

2. 配置Newtonsoft.Json

public void ConfigureServices(IServiceCollection services)
{
services.AddControllers()
.AddNewtonsoftJson(options => //添加基于NewtonsoftJson格式化
{
options.SerializerSettings.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat;
options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
options.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
});
}
 
JSON Patch请求

PUT 和 PATCH 方法用于更新现有资源。 它们之间的区别是,PUT 会替换整个资源,而PATCH 仅指定更改。

什么是JSON Patch?

JSON Patch官网 里面有一句介绍的很清楚:JSON Patch is a format for describing changes to a JSON document. (一种描述Json的变化的格式)

什么时候需要用到JSON Patch

  1. 我们返回的JSON很大,修改可能只是某些字段
  2. 对性能要求比较大的地方
  3. 一个大的对象,好几个地方修改,然后统一接口修改

ASPNET Core如何处理JSON Patch 请求

1. 添加包支持

dotnet add package Microsoft.AspNetCore.JsonPatch

2. 使用 HttpPatch 属性进行批注

3. 接受 JsonPatchDocument<T>,通常带有 [FromBody]

4. 调用 ApplyTo 以应用更改

假设我们现在有一个完成订单的需求

  1. 检查金额,数量是否有变更
  2. 更新IsComplete = true

下面附上代码和提交的JSON

控制器代码

[HttpPatch("{orderNo:length(18)}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<bool> Update([FromBody] JsonPatchDocument<Models.Order> patchDoc, [FromRoute] string orderNo)
{
var order = _orderStore.Orders.FirstOrDefault(m => m.OrderNo == orderNo); if (order == null)
{
return NotFound();
} patchDoc.ApplyTo(order, ModelState); if (!ModelState.IsValid)
{
return BadRequest(ModelState);
} return Ok(true);
}

失败的JSON(金额校验不过)

PATCH  {{baseUrl}}/Order/ HTTP/1.1
Accept: application/json
Content-Type: application/json [
{
"op": "test",
"path": "/quantity",
"value": ""
},
{
"op": "test",
"path": "/amount",
"value": "38.28"
},
{
"op": "add",
"path": "/isComplete",
"value": "true"
},
]

会在ModelState里面列出校验不过的信息

成功的JSON

PATCH  {{baseUrl}}/Order/ HTTP/1.1
Accept: application/json
Content-Type: application/json [
{
"op": "test",
"path": "/quantity",
"value": ""
},
{
"op": "test",
"path": "/amount",
"value": "36.8"
},
{
"op": "add",
"path": "/isComplete",
"value": "true"
},
]

我们用Get请求重新查一下,可以看到IsComplete成功被修改了

这里只是简单介绍JSON Patch使用,更多使用方法参考JSON Pan官网微软文档

Open API(Swagger)集成

Api 通常需要跟客户端,前端进行沟通,需要编写文档,这需要花费大量时间。

Open Api是专门解决这种问题,它为RESTful api定义了一个标准的、与语言无关的接口,利用工具生成文档,可以做到代码即文档(逼着开发者完善注释)

ASPNET Core 可以使用Swashbuckle.AspNetCoreNSwag 生成Swagger 文档

下面介绍如何使用Swashbuckle.AspNetCore

一、使用Swashbuckle.AspNetCore

  1. 安装Swashbuckle.AspNetCore包

    dotnet add package Swashbuckle.AspNetCore
  2. 添加并配置 Swagger 中间件

    引用命名空间:using Microsoft.OpenApi.Models;

    services.AddSingleton<Models.OrderStore>();
    
    services.AddSwaggerGen(c =>
    {
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "Web Api Doc", Version = "v1" });
    });
    app.UseSwagger();
    
    app.UseSwaggerUI(c =>
    {
      c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
    });

     经过上面两步就可以使用SwaggerUI来查看文档和测试,浏览器打开(http://{url}/swagger)

二、添加XML注释

上面生成的Swagger文档是不包含XML注释,下面介绍如何添加XML注释

  1. 项目文件(*.csproj)添加以下

    <PropertyGroup>
        <GenerateDocumentationFile>true</GenerateDocumentationFile>
        <NoWarn>$(NoWarn);1591</NoWarn>
    </PropertyGroup>

    加上上面生成文档后,未注释的函数,属性会发出警告,警告代码1591,忽略警告可以添加多个,分号分割

  2. AddSwaggerGen添加下面XML支持

    services.AddSwaggerGen(c =>
    {
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "Web Api Doc", Version = "v1" }); var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
    var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
    c.IncludeXmlComments(xmlPath);
    });
  3. 方法添加注释

    /// <summary>
    /// 更新订单指定信息
    /// </summary>
    /// <remarks>
    /// Sample request:
    ///
    /// PATCH /Order/{orderNo}
    /// [
    /// {
    /// "op": "test",
    /// "path": "/quantity",
    /// "value": "2"
    /// },
    /// {
    /// "op": "test",
    /// "path": "/amount",
    /// "value": "38.28"
    /// },
    /// {
    /// "op": "add",
    /// "path": "/isComplete",
    /// "value": "true"
    /// },
    /// ]
    /// </remarks>
    /// <returns>返回是否成功</returns>
    /// <response code="200">提交成功</response>
    /// <response code="400">提交参数异常</response>
    /// <response code="404">订单号不存在</response>

    ProducesResponseType 描述返回类型

    remarks 会生成请求说明

  4. 效果

Web Api 使用就介绍这些,如有错漏,希望指出。

转发请标明出处:https://www.cnblogs.com/WilsonPan/p/11945856.html

示例代码:https://github.com/WilsonPan/AspNetCoreExamples/tree/master/WebApi

【ASP.NET Core学习】Web API的更多相关文章

  1. angular4和asp.net core 2 web api

    angular4和asp.net core 2 web api 这是一篇学习笔记. angular 5 正式版都快出了, 不过主要是性能升级. 我认为angular 4还是很适合企业的, 就像.net ...

  2. 温故知新,使用ASP.NET Core创建Web API,永远第一次

    ASP.NET Core简介 ASP.NET Core是一个跨平台的高性能开源框架,用于生成启用云且连接Internet的新式应用. 使用ASP.NET Core,您可以: 生成Web应用和服务.物联 ...

  3. 使用angular4和asp.net core 2 web api做个练习项目(一)

    这是一篇学习笔记. angular 5 正式版都快出了, 不过主要是性能升级. 我认为angular 4还是很适合企业的, 就像.net一样. 我用的是windows 10 安装工具: git for ...

  4. 使用angular4和asp.net core 2 web api做个练习项目(四)

    第一部分: http://www.cnblogs.com/cgzl/p/7755801.html 第二部分: http://www.cnblogs.com/cgzl/p/7763397.html 第三 ...

  5. 基于ASP.NET Core 创建 Web API

    使用 Visual Studio 创建项目. 文件->新建->项目,选择创建 ASP.NET Core Web 应用程序. 基于 ASP.NET Core 2.0 ,选择API,身份验证选 ...

  6. ASP.NET Core Restful Web API 相关资源索引

    GraphQL 使用ASP.NET Core开发GraphQL服务器 -- 预备知识(上) 使用ASP.NET Core开发GraphQL服务器 -- 预备知识(下) [视频] 使用ASP.NET C ...

  7. 使用angular4和asp.net core 2 web api做个练习项目(二), 这部分都是angular

    上一篇: http://www.cnblogs.com/cgzl/p/7755801.html 完成client.service.ts: import { Injectable } from '@an ...

  8. 使用 ASP.NET Core 创建 Web API及链接sqlserver数据库

    创建 Web API https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/first-web-api?view=aspnetcore-3.0& ...

  9. 使用angular4和asp.net core 2 web api做个练习项目(三)

    第一部分: http://www.cnblogs.com/cgzl/p/7755801.html 第二部分: http://www.cnblogs.com/cgzl/p/7763397.html 后台 ...

  10. ASP.NET Core 中基于 API Key 对私有 Web API 进行保护

    这两天遇到一个应用场景,需要对内网调用的部分 web api 进行安全保护,只允许请求头账户包含指定 key 的客户端进行调用.在网上找到一篇英文博文 ASP.NET Core - Protect y ...

随机推荐

  1. Linux读取外存

    Linux系统不像Windows系统那样,U盘自动识别,即插即用,Linux需要手动挂载U盘.步骤如下: 1.查看闪存: fdisk -l 2.添加挂载目录,一般放在/mnt下 mkdir /mnt/ ...

  2. Maven optional关键字透彻图解

    写在前面 本来想写一篇「如何自定义Spring Boot Starter」,但是为了更好理解 Starter 的一些设计理念和其中的关键点,所以提前将一些细节内容单独提取出来讲解说明 在 Maven ...

  3. abp(net core)+easyui+efcore实现仓储管理系统——EasyUI之货物管理七(二十五)

    abp(net core)+easyui+efcore实现仓储管理系统目录 abp(net core)+easyui+efcore实现仓储管理系统——ABP总体介绍(一) abp(net core)+ ...

  4. Dubbo 全链路追踪日志的实现

    微服务架构的项目,一次请求可能会调用多个微服务,这样就会产生多个微服务的请求日志,当我们想要查看整个请求链路的日志时,就会变得困难,所幸的是我们有一些集中日志收集工具,比如很热门的ELK,我们需要把这 ...

  5. (八十六)c#Winform自定义控件-表格优化

    出处:http://www.hzhcontrols.com/原文:http://www.hzhcontrols.com/blog-149.html本文版权归www.hzhcontrols.com所有欢 ...

  6. 一文搭建自己博客/文档系统:搭建,自动编译和部署,域名,HTTPS,备案等

    本文纯原创,搭建后的博客/文档网站可以参考: Java 全栈知识体系.如需转载请说明原处. 第一部分 - 博客/文档系统的搭建 搭建博客有很多选择,平台性的比如: 知名的CSDN, 博客园, 知乎,简 ...

  7. Linux系统 multitail 同时跟踪查看多个日志文件

    一.问题描述: 平时我们在排查问题的时候往往需要查看日志文件来定位问题,有些程序可能关联的多个程序,因此需要打开多个窗口使用 tailf 或者tail -f 方式查看日志 但是需要不停的切换窗口来看不 ...

  8. [2018-01-12] python 当天学习笔记

    Python模块 Python欧快(Moudule),是一个Python文件,以.py结尾,包含了Python对象定义和Python语句. 模块让你能够有逻辑地组织你的Python代码段. 把相关的代 ...

  9. android studio ndk 环境配置成eclipse模式

    gradle.properties: android.useDeprecatedNdk=true build.gradle: android { ... sourceSets.main { jni.s ...

  10. Docker的centos7容器中如何安装mongodb

    下载安装包: wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.2.12.tgz 解压安装包 tar -zxvf mongodb ...