【ASP.NET Core】体验一下 Mini Web API
在上一篇水文中,老周给大伙伴们简单演示了通过 Socket 编程的方式控制 MPD (在树莓派上)。按照计划,老周还想给大伙伴们演示一下使用 Web API 来封装对 MPD 控制。思路很 Easy,树莓派上使用本地 Socket 来封装一下,然后以 Web API 的方式对客户端公开。这样有一个好处:之后不管你打算把客户端做成桌面窗口,还是 Web 页面,或是做成手机 App,你都可以直接调用这套 Web API。这样一来,很多代码就不必重复写了,省时省力,减少脑细胞的大量死亡。
如果大家比较关心时事的话,应该知道 .NET 6 的 ASP.NET Core 有一个新特性—— Mini API,或 Mini Web API。有一个不错的翻译叫做“极简 API”。其实,极简的不只是 Web API,整个 ASP.NET Core 应用项目的结构都精简了不少。最让老周高兴的就是没有了 Startup 类(其实早期版本中也可以不使用 Startup,如果你以前看过老周的误人子弟教程的话,你应该有印象),也不用费心地搞个什么 ConfigureService 又要弄个 Configure 方法约定了。再配合 C# 9 的新功能,连 Main 方法都省了。所以初始化配置工作都可以在一个代码文件中搞定。
使用这个简化版的 Web API 来做 MPD 的封装还真的不错。不过,本文老周先不弄这个,先让大伙伴们了解一下 Mini API 怎么玩——权且当作预备知识。
.NET 6 还有个新功能也不错,就是全局的 using 指令。以前在 C 语言中,如果你写一个 abc.h 头文件,里面放上这些代码:
#ifndef _ABC_H_
#define _ABC_H_ #include "nc.h"
#include "nt.h"
#include "zz.h"
#include "xb.h"
#include "sb.h" #endif
然后在代码文件中 include 一个这个 abc.h 就可以间接引用这些头文件,但 C# 中没有这种玩法,每个代码文件要用到哪些命名空间,都要写一遍 using 指令。在随同 .NET 6 一同发布的 C# 10 中终于有全局 using 了。只要你在其中一个代码文件中写上全局 using 指令,然后其他代码文件中就不必再 using 了。
方法是在 using 前加上 global 就行了。C# 虽然早有 global 关键字,但在过去这个并不是全局 using 用的,而是专用来标识 .NET 框架中的命名空间的,主要是防止命名空间重名的。
好了,咱们现在就去嗨一下 Mini API吧。
此处假设你已经安装好 VS 2022 和 .NET 6。在创建新项目时选择空白 ASP.NET Core 应用程序。用空白项目方便稍后写自己的 Code。
然后输入项目名称以及存放路径。
选择.net 版本号。
最后,确定新创建项目。
---------------------------------------------------------------------------------
项目创建后你会发现,真TM简洁了不少,Program.cs 文件中只有这么几行。
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build(); app.MapGet("/", () => "Hello World!"); app.Run();
第一行:调用 CreateBuilder 方法创建一个builder ,这个 builder 随后用于构建 Web 应用程序。
第二行:直接就用预设的参数构建了一个 app 对象。
第三行:配置 HTTP 管道——怎么处理HTTP请求。此处配置表明只向客户端返回“Hello World!”。
第四行:运行 app。
你,不用再写 Startup 类了,也不用遵守方法签约定去写 ConfigureServices 等方法了。
要配置服务咋办?直接 Services Add。例如
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddRazorPages();
builder.Services.AddAntiforgery()
.AddWebEncoders()
.AddSingleton<XXX, YYY>();
var app = builder.Build();
app.MapGet("/", () => "Hello World!"); app.Run();
看看是不是很整齐?注意这个过程是在 build 方法调用之前完成的。原因和以前 Startup 类中写方法一样,Add 服务是声明咱们的应用程序中要使用哪些功能,哪些对象被用于依赖注入,一旦 build 了,程序的功能结构就确定下来了,所以应用程序构建后就不再修改其功能了。
以前在写 Startup 时,我们知道,还有一个 Configure 方法用来配置中间件的,也就是刚刚说的配置HTTP管道。build 方法构建 app 后,就可以直接通过这个 app 实例来配置你要 Use 的东西。例如
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
// 中间件配置
app.MapGet("/", () => "Hello World!");
app.UseRouting();
app.UseCookiePolicy();
app.Use(async (context, next) =>
{
context.Response.Headers.Add("Server", "Big Bomb");
await next();
});
app.MapControllers();
app.MapBlazorHub();
app.MapRazorPages();
app.Run();
如果我们要编写 Mini API,不需要 Add 什么 Service,也不需要 Use 什么组件,在 build 和 app.run 之间直接 MapXXX 就行了。XXX 指 HTTP 请求方法,比如 GET、POST、PUT 等。
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
//====================================
// Mini API 写在这里
//====================================
app.Run();
相当有意思的是:这些 MapXXX 扩展方法都有一个 handler 参数,类型是 Delegate。也就是说你在调用时可以传递任何类型的委托对象。于是,就可以这样搞:
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build(); app.UseHttpsRedirection();
//====================================
// Mini API 写在这里
app.MapGet("/greet", () =>
{
return "What the fuck?";
});
//====================================
app.Run();
一个 Web API 就完成了。真的,可以用了,不信运行下看看。拿出秘密武器——Postman,测试一下。
用 Postman 还是有些不够爽,而且这货现在越做越复杂,还整天叫你注册帐号,实属无趣。我们改为用 swagger 来测试。打开 Nuget 包管理器,搜索 swagger。
安装这个包包。
把代码改一下。
var builder = WebApplication.CreateBuilder(args);
// 不要忘了加这两个服务
builder.Services.AddSwaggerGen();
builder.Services.AddEndpointsApiExplorer();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
//====================================
// Mini API 写在这里
app.MapGet("/greet", () =>
{
return "What the fuck?";
});
//====================================
app.Run();
这样一来,咱们在开发测试阶段就可以直接用这个组件在 Web 页上测试 API 的调用了,不再启动其他工具软件了。
运行该项目,然后浏览器定位到 http(s)://root_url:port/swagger。
比如,我运行后得到的URL是 https://localhost:7189,那么在浏览器中打开 https://localhost:7189/swagger。
点击右边的“try it out”,然后点 “Execute” 按钮,就能看到执行结果了。
怎么样,好用吧?咱们再添加一个API,这次要带参数的 POST 请求。
app.MapPost("/submit", (string name, int age) =>
{
return $"你提交的内容:{name} - {age}";
});
这个 API 带两个参数,分别取名为 name,age。在调用时,是通过请求的 body 来提供的,格式为 JSON。
前面老周说过,这些MapXXX方法的委托参数是 Delegate 类型,所以你可以用任意类型的委托,有参数的没参数的,有返回值的没返回值的。
每次调试时都要在浏览器地址输入 http(s)://root/swagger 太TM不方便了,咱们可以配置一下,让其自动定位到 swagger 下。打开项目属性窗口,转到“调试”标签。
点击页面上的“打开调试启动配置文件 UI”链接。
把滚动条往地狱方向拉,一直拉到看到“URL”标题,在文本中填上 swagger。搞定。
现在,你直接运行项目,就自动打开 API 列表了。点击展开 submit,再点“try it out”。
为 name 和 age 参数填上值,执行。
下面再举一例,请求方式为 GET,参数来自 URL 查询(即带 ? 的URL,如 /abc?t=3000)。
app.MapGet("/md5", ([FromQuery(Name = "msg")] string data) =>
{
byte[] buffer = Encoding.UTF8.GetBytes(data);
using MD5 md5ec = MD5.Create();
byte[] comres = md5ec.ComputeHash(buffer);
return $"加密结果:{Convert.ToHexString(comres).ToLower()}";
});
这个 API 的功能:接收一个字符串类型的对象,对其作 MD5 运算,然后返回结果。这个请求是从查询字符串中得到参数 data 的值的,所以要加上 FromQuery 特性,而且,实际传值时查询参数的名称与API的参数名称不同,故要用 Name = .... 明确指定,要从 msg 查询参数中提取值。
综上,此API的调用方式为 GET /md5?msg=呵呵哈哈呵呵哈。
咱们玩这一步了,你心中一定有个高大上的疑问:这货支持依赖注入乎?
很好,老周也有此疑问,要不,咱们搞搞看。
public interface IComputer
{
int RunIt(int x, int y, int z);
} internal class ComputerService : IComputer
{
public int RunIt(int x, int y, int z)
{
return x - y - z;
}
}
我定义了一个服务接口,里面有个 RunIt 方法;然后俺实现之。逻辑很简单,x、y、z 三数相减。
接下来改代码,在 build 方法调用之前注册服务,咱们就注册个单实例模式吧,全局共享一个实例。
var builder = WebApplication.CreateBuilder(args);
……
builder.Services.AddSingleton<IComputer, ComputerService>();
然后,我们完成 API。
app.MapPost("/comp", (int n1, int n2, int n3, IComputer compsv) =>
{
int r = compsv.RunIt(n1, n2, n3);
return $"计算结果:{r}";
});
不要犹豫,运行它!
得到结果:
在这个API中,n1,n2,n3 三个参数是从客户端 POST 过来的,而最后一个参数是通过依赖注入得到引用对象的。那么,把参数的位置调换一下,是否也可行呢?
app.MapPost("/comp", (IComputer compsv, int n1, int n2, int n3) =>
{
int r = compsv.RunIt(n1, n2, n3);
return $"计算结果:{r}";
});
然后再测,结果表明,是可行滴。
好了,今天的话题就聊到这儿了,下次咱们就用这个 Mini API 来封装 MPD。
【ASP.NET Core】体验一下 Mini Web API的更多相关文章
- 002.Create a web API with ASP.NET Core MVC and Visual Studio for Windows -- 【在windows上用vs与asp.net core mvc 创建一个 web api 程序】
Create a web API with ASP.NET Core MVC and Visual Studio for Windows 在windows上用vs与asp.net core mvc 创 ...
- ASP.NET Core MVC中构建Web API
在ASP.NET CORE MVC中,Web API是其中一个功能子集,可以直接使用MVC的特性及路由等功能. 在成功构建 ASP.NET CORE MVC项目之后,选中解决方案,先填加一个API的文 ...
- ASP.NET Core 1.0开发Web API程序
.NET Core版本:1.0.0-rc2Visual Studio版本:Microsoft Visual Studio Community 2015 Update 2开发及运行平台:Windows ...
- 【asp.net core】实现动态 Web API
序言: 远程工作已经一个月了,最近也算是比较闲,每天早上起床打个卡,快速弄完当天要做的工作之后就快乐摸鱼去了.之前在用 ABP 框架(旧版)的时候就觉得应用服务层写起来真的爽,为什么实现了个 IApp ...
- 【ASP.NET Core】从向 Web API 提交纯文本内容谈起
前些时日,老周在升级“华南闲肾回收登记平台”时,为了扩展业务,尤其是允许其他开发人员在其他平台向本系统提交有关肾的介绍资料,于是就为该系统增加了几个 Web API. 其中,有关肾的介绍采用纯文本方式 ...
- ASP.NET Core WebApi使用Swagger生成api说明文档看这篇就够了
引言 在使用asp.net core 进行api开发完成后,书写api说明文档对于程序员来说想必是件很痛苦的事情吧,但文档又必须写,而且文档的格式如果没有具体要求的话,最终完成的文档则完全取决于开发者 ...
- ASP.NET Core WebApi使用Swagger生成api
引言 在使用asp.net core 进行api开发完成后,书写api说明文档对于程序员来说想必是件很痛苦的事情吧,但文档又必须写,而且文档的格式如果没有具体要求的话,最终完成的文档则完全取决于开发者 ...
- 【转】ASP.NET Core WebApi使用Swagger生成api说明文档看这篇就够了
原文链接:https://www.cnblogs.com/yilezhu/p/9241261.html 引言 在使用asp.net core 进行api开发完成后,书写api说明文档对于程序员来说想必 ...
- ASP.NET Core WebApi使用Swagger生成api说明文档
1. Swagger是什么? Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.总体目标是使客户端和文件系统作为服务器以同样的速度来更新.文件 ...
随机推荐
- 【死磕NIO】— 阻塞IO,非阻塞IO,IO复用,信号驱动IO,异步IO,这你真的分的清楚吗?
通过上篇文章([死磕NIO]- 阻塞.非阻塞.同步.异步,傻傻分不清楚),我想你应该能够区分了什么是阻塞.非阻塞.异步.非异步了,这篇文章我们来彻底弄清楚什么是阻塞IO,非阻塞IO,IO复用,信号驱动 ...
- Stream之高级函数
上回文说到了有关Stream一些数学函数的用法.今天来说下Stream一些高级的函数用法,这些函数在日常工作中也是必不可少的,测试数据还是引用上一篇的数据. Map 这个方法我个人称之为转换函数,把一 ...
- ldirectord
试想,LVS作为前端负载均衡设备,当后端服务器宕机时,LVS还会把用户请求发送到该服务器上,这对用户体验来说是极其糟糕的,因为用户的请求无法得到处理.那么是否有一种机制,能保证后端服务器的是否正常?或 ...
- 11.5.1 LVS-DR 实验
lvs-server VIP:10.211.55.99 DIP:10.211.55.23 负载均衡器 rs01 RIP:10.211.55.24 后端服务器 rs02 RIP:10.211.5 ...
- Django实现用户登录注册
本文将会介绍小白如何完成一个用户登录注册系统 新建一个Django项目,名字为login_register,并且使用命令manage.py startapp.User(名字自己随便起) 最终djang ...
- 单体应用 适合采用 dapr 构建吗?
缘起今天在微信群里有同学问 "纯.net 项目,有必要上dapr吗?" 当时不假思索的说不是微服务没必要,其他群友也说没必要.下午细想了一下,觉得这个和微服务没有关系,如果我的应用 ...
- 网络协议之:加密传输中的NPN和ALPN
目录 简介 SSL/TLS协议 NPN和ALPN 交互的例子 总结 简介 自从HTTP从1.1升级到了2,一切都变得不同了.虽然HTTP2没有强制说必须使用加密协议进行传输,但是业界的标准包括各大流行 ...
- Java(25)常见异常整理
作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15228418.html 博客主页:https://www.cnblogs.com/testero ...
- JavaScript兼容性汇总
一般兼容性问都体现到DOM和事件上 只聊ie6+版本浏览器,希望小伙伴们别纠结更低版本浏览器哈^_^ DOM 获取元素 document.getElementsByclassName 不兼容ie6 ...
- 【UE4 C++】解析与构建 XML 数据,XmlParser 与 tinyxml
XmlParser 简单读取 XmlParser 为引擎自带模块 XML 文件 <?xml version="1.0" encoding="UTF-8"? ...