我们先创建一个 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 概述的更多相关文章

  1. ASP.NET Core 2.2 基础知识(十八) 托管和部署 概述

    为了方便演示,以 .NET Core 控制台应用程序讲解. 我们新建一个控制台应用程序,安装 "Newtonsoft.Json" Nuget 包,然后右键点击该项目,选择" ...

  2. ASP.NET Core 2.2 基础知识(十二) 发送 HTTP 请求

    可以注册 IHttpClientFactory 并将其用于配置和创建应用中的 HttpClient 实例. 这能带来以下好处: 提供一个中心位置,用于命名和配置逻辑 HttpClient 实例. 例如 ...

  3. ASP.NET Core 2.2 基础知识(十六) SignalR 概述

    我一直觉得学习的最好方法就是先让程序能够正常运行,才去学习他的原理,剖析他的细节. 就好像这个图: 所以,我们先跟着官方文档,创建一个 SignalR 应用: https://docs.microso ...

  4. ASP.NET Core 2.2 基础知识(十四) WebAPI Action返回类型(未完待续)

    要啥自行车,直接看手表 //返回基元类型 public string Get() { return "hello world"; } //返回复杂类型 public Person ...

  5. ASP.NET Core 2.2 基础知识(十一) ASP.NET Core 模块

    ASP.NET Core 应用与进程内的 HTTP 服务器实现一起运行.该服务器实现侦听 HTTP 请求,并在一系列请求功能被写到 HttpContext 时,将这些请求展现到应用中. ASP.NET ...

  6. ASP.NET Core 2.2 基础知识(十) Web服务器 - Kestrel

    ASP.NET Core 应用与进程内的 HTTP 服务器实现一起运行.该服务器实现侦听 HTTP 请求,并在一系列请求功能被写到 HttpContext 时,将这些请求展现到应用中. ASP.NET ...

  7. ASP.NET Core 2.2 基础知识(九) 使用托管服务实现后台任务

    在 ASP.NET Core 中,后台任务作为托管服务实现.托管服务是一个类,而且必须实现 IHostedService 接口,该接口定义了两个方法: StartAsync(CancellationT ...

  8. ASP.NET Core 2.2 基础知识(八) 主机 (未完待续)

    主机负责应用程序启动和生存期管理.共有两个主机 API : 1.Web 主机 : 适用于托管 Web 应用,基于 IWebHostBuilder ; 2.通用主机 : 适用于托管非 Web 应用. 基 ...

  9. ASP.NET Core 2.2 基础知识(六) 配置(内含MySql+EF)

    先上一段代码,了解一下 .NET Core 配置数据的结构. 新建一个 控制台项目,添加一个文件 json.json ,文件内容如下: { "country": "cn& ...

随机推荐

  1. 使用def文件简化dll导出

    原文链接地址:http://www.cnblogs.com/TianFang/archive/2013/05/04/3059073.html 在C++中,我们可以通过 __declspec(dllex ...

  2. [HEOI2015]最短不公共子串

    四合一的题. 简单粗暴的方法: 子串匹配——SAM 子序列匹配——序列自动机 关于序列自动机:序列自动机—— [FJOI2016]所有公共子序列问题 (其实这个玩意没有什么,n+1个点,每个点的字符集 ...

  3. springboot与dubbo结合

    转:http://www.cnblogs.com/Alandre/p/6490142.html  写的很好! 本文提纲 一.为啥整合 Dubbo 实现 SOA 二.运行 springboot-dubb ...

  4. lwIP内存管理机制

    lwip的内存管理机制,我们以enet_lwip这个例程为例. 在使用lwip的时候,我们可以使用两种形式的内存,一种是heap(mem.c文件-mem_malloc()),一种是pool(memp. ...

  5. Error in deleting blocks.

    2014-08-24 22:15:21,714 WARN org.apache.hadoop.hdfs.server.datanode.DataNode: Error processing datan ...

  6. [CVPR2017]Online Video Object Segmentation via Convolutional Trident Network

    基于三端卷积网络的在线视频目标分割 针对半监督视频目标分割任务,作者采取了和MaskTrace类似的思路,以optical flow为主. 本文亮点在于: 1. 使用共享backbone,三输出的自编 ...

  7. webpack 引入 html-webpack-plugin 报错

    配置webpack当中,出现一个问题: 引入html-webpack-plugin 插件报错. 这时需要本地(也就是当前项目下)安装一下webpack就可以解决问题了. 注意:现在是webpack4版 ...

  8. 转:nginx入门指南,快速搭建静态文件服务器和代理服务器

    本文介绍 Nginx 入门基础知识,让你迅速搭建 Nginx 服务器.主要内容包括 Nginx 安装和简单使用.Nginx的简单原理.Nginx 配置文件的结构.如何使用 Nginx 来提供静态文件服 ...

  9. idea真不习惯啊

    http://blog.csdn.net/z69183787/article/details/41416189

  10. [bzoj1208][HNOI2004]宠物收养所——splay

    题目大意 Description 最近,阿Q开了一间宠物收养所.收养所提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物.每个领养者都希望领养到自己满意的宠物,阿Q根据领养者的要求通过他自己发 ...