ASP.NET Core 2.2 基础知识(十三) WebAPI 概述
我们先创建一个 WebAPI 项目,看看官方给的模板到底有哪些东西
官方给出的模板:
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
// GET api/values
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "value1", "value2" };
} // GET api/values/5
[HttpGet("{id}")]
public ActionResult<string> Get(int id)
{
return "value";
} // POST api/values
[HttpPost]
public void Post([FromBody] string value)
{
} // PUT api/values/5
[HttpPut("{id}")]
public void Put(int id, [FromBody] string value)
{
} // DELETE api/values/5
[HttpDelete("{id}")]
public void Delete(int id)
{
}
}
同时,在 Startup 类中注册了 Mvc 中间件.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
} app.UseHttpsRedirection();
app.UseMvc();
}
实际上, 继承 ControllerBase ,特性 [Route] [ApiController] 都是为了提供一些便利功能,一个最"轻量"的 WebAPI 是这样的:
新建一个 TestController:
public class TestController
{
public string Get()
{
return "hello world";
}
}
啥也没有,很干净.
注册 Mvc 中间件时添加路由:
//app.UseMvc(route => { route.MapRoute("default", "api/{controller}"); });//不能这样写,这种最轻量的方式,不支持 Restful 风格的请求方式
app.UseMvc(route => { route.MapRoute("default", "api/{controller}/{action}"); });
测试:
当然,我们也可以不在 注册 Mvc 中间件的时候添加路由,还是像官方推荐的那样,在控制器上利用路由特性,这种方式就支持 Restful 风格的请求方式了.
[Route("api/[controller]")]
public class TestController
{
public string Get()
{
return "hello world";
}
}
那 ControllerBase 提供了哪些便利功能呢?看源码就明白了:
截一小部分图:
[ApiController] 特性则提供如下便利功能:
绑定源参数推理
当没有[ApiController]特性时,参数绑定都默认从QueryString获取.假设有如下控制器和实体类:
[Route("api/[controller]")]
public class TestController
{
public string Get(Person person, int id, string name, Student student)
{
var temp = new { person, id, name, student };
return JsonConvert.SerializeObject(temp);
}
}
public class Person
{
public int Id { get; set; } public string Name { get; set; }
} public class Student
{
public int Id { get; set; } public string Name { get; set; }
}
请求结果:
可以看到,所有的参数都绑定上了.
但工作中,复杂类型我们一般都是 post 提交,写在 body 里面.
现在我们改用post提交 ,稍微修改一下 action :
[Route("api/[controller]")]
public class TestController
{
public string Get(Person person)
{
return JsonConvert.SerializeObject(person);
}
}
请求:
结果没有绑定上:
这也证明了 在没有 [ApiController] 特性时,默认都是从 QueryString 获取参数来绑定.
上述例子要想绑定成功,需要给 action 的入参打上 [FromBody] 特性:
public string Get([FromBody]Person person)
{
return JsonConvert.SerializeObject(person);
}
请求结果:
ASP.NET Core 的绑定特性似乎比 ASP.NET 多了一些,下面是官网给的:
如果 Controller 上应用了 [ApiController] 特性,那么框架会根据参数类型自动选择绑定特性.
现在我们给 TestController 应用 [ApiController] 特性,同时删掉 Action 上的 [FromBody] 特性:
[Route("api/[controller]")]
[ApiController]
public class TestController
{
public string Get(Person person)
{
return JsonConvert.SerializeObject(person);
}
}
请求结果:
至于自动选择绑定特性的规则,我也没有全部测试,不过我感觉应该和 ASP.NET 是一样的.
但是,有个地方不一样,不知道算不算 ASP.NET Core 的优化:
对于之前的 ASP.NET WebAPI ,如果 QueryString 的参数没有涵盖 Action 上定义的所有参数,那么是请求不到该 Action 的.
比如,这是一个 ASP.NET WebAPI 控制器,Get 方法定义了两个入参:
public class TestController : ApiController
{
public string Get(int id,string name)
{
var temp = new {id, name};
return JsonConvert.SerializeObject(temp);
}
}
那么,如果我们的 QueryString 只传递了其中一个,是请求不到 Get 方法的.
但是, ASP.NET Core 是可以的:
上面提到的这个自动选择绑定特性的规则,可以通过代码来禁止(红色部分,其余的是禁用 [ApiController] 特性提供的其他便利功能的):
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
.ConfigureApiBehaviorOptions(options =>
{
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
options.SuppressMapClientErrors = true;
options.ClientErrorMapping[].Link =
"https://httpstatuses.com/404";
});
至于其他便利功能,可以查看官方文档:https://docs.microsoft.com/zh-cn/aspnet/core/web-api/?view=aspnetcore-2.2
其实我写的这些,大多数都是抄的官方文档.
ASP.NET Core 2.2 基础知识(十三) WebAPI 概述的更多相关文章
- ASP.NET Core 2.2 基础知识(十八) 托管和部署 概述
为了方便演示,以 .NET Core 控制台应用程序讲解. 我们新建一个控制台应用程序,安装 "Newtonsoft.Json" Nuget 包,然后右键点击该项目,选择" ...
- ASP.NET Core 2.2 基础知识(十二) 发送 HTTP 请求
可以注册 IHttpClientFactory 并将其用于配置和创建应用中的 HttpClient 实例. 这能带来以下好处: 提供一个中心位置,用于命名和配置逻辑 HttpClient 实例. 例如 ...
- ASP.NET Core 2.2 基础知识(十六) SignalR 概述
我一直觉得学习的最好方法就是先让程序能够正常运行,才去学习他的原理,剖析他的细节. 就好像这个图: 所以,我们先跟着官方文档,创建一个 SignalR 应用: https://docs.microso ...
- ASP.NET Core 2.2 基础知识(十四) WebAPI Action返回类型(未完待续)
要啥自行车,直接看手表 //返回基元类型 public string Get() { return "hello world"; } //返回复杂类型 public Person ...
- ASP.NET Core 2.2 基础知识(十一) ASP.NET Core 模块
ASP.NET Core 应用与进程内的 HTTP 服务器实现一起运行.该服务器实现侦听 HTTP 请求,并在一系列请求功能被写到 HttpContext 时,将这些请求展现到应用中. ASP.NET ...
- ASP.NET Core 2.2 基础知识(十) Web服务器 - Kestrel
ASP.NET Core 应用与进程内的 HTTP 服务器实现一起运行.该服务器实现侦听 HTTP 请求,并在一系列请求功能被写到 HttpContext 时,将这些请求展现到应用中. ASP.NET ...
- ASP.NET Core 2.2 基础知识(九) 使用托管服务实现后台任务
在 ASP.NET Core 中,后台任务作为托管服务实现.托管服务是一个类,而且必须实现 IHostedService 接口,该接口定义了两个方法: StartAsync(CancellationT ...
- ASP.NET Core 2.2 基础知识(八) 主机 (未完待续)
主机负责应用程序启动和生存期管理.共有两个主机 API : 1.Web 主机 : 适用于托管 Web 应用,基于 IWebHostBuilder ; 2.通用主机 : 适用于托管非 Web 应用. 基 ...
- ASP.NET Core 2.2 基础知识(六) 配置(内含MySql+EF)
先上一段代码,了解一下 .NET Core 配置数据的结构. 新建一个 控制台项目,添加一个文件 json.json ,文件内容如下: { "country": "cn& ...
随机推荐
- 移动开发:美团外卖Android Lint代码检查实践
概述 Lint是Google提供的Android静态代码检查工具,可以扫描并发现代码中潜在的问题,提醒开发人员及早修正,提高代码质量.除了Android原生提供的几百个Lint规则,还可以开发自定义L ...
- 版本7以上IE以文件夹视图方式打开FTP的解决
一.问题的提出 版本7以上IE浏览器打开FTP时只出现列表 二.问题的解决 设置ie浏览器选项即可,以ie9为例,设置步骤如下: 1.启动ie,点击设置按钮,弹出菜单选择internet选项命令: 2 ...
- HDU 2639 01背包求第k大
Bone Collector II Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- Wpremig和Jhadgre的藏宝图(最大流+二分)
Wpremig和Jhadgre的藏宝图 题目链接:https://ac.nowcoder.com/acm/contest/333/M Description: Jhadgre在生日那天收到了一张神秘的 ...
- kafka.common.ConsumerRebalanceFailedException异常解决
kafka.common.ConsumerRebalanceFailedException: group_dd-1446432618163-2746a209 can't rebalance after ...
- 栈与递归的实现(Hanoi塔问题等等)
函数中有直接或间接地调用自身函数的语句,这样的函数称为递归函数.递归函数用 得好,可简化编程工作.但函数自己调用自己,有可能造成死循环.为了避免死循环,要 做到两点: (1) 降阶.递归函数虽然调用自 ...
- 前端面试:提升web性能
1,减少HTTP请求数 A,从设计实现层简化页面 B,合理设置HTTP缓存 C,资源合并与压缩.如果可以的话,尽可能的将外部脚本,央视进行合并,多个合为一,css,javascript,image都可 ...
- [BZOJ1031][JSOI2007]字符加密Cipher 解题报告
Description 喜欢钻研问题的JS 同学,最近又迷上了对加密方法的思考.一天,他突然想出了一种他认为是终极的加密办法:把需要加密的信息排成一圈,显然,它们有很多种不同的读法.例如下图,可以读作 ...
- 【STSRM12】夏令营
[题意]n个数划分成k段,每段的价值为段内不同数字的数量,求最大总价值 [算法]DP+线段树 [题解] f[i][j]表示前i个数字划分成j段的最大价值. f[i][j]=max(f[k][j-1]+ ...
- HDU1068 (二分图最大匹配匈牙利算法)
Girls and Boys Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...