Controller和路由

  1. using Microsoft.AspNetCore.Http;
  2. using Microsoft.AspNetCore.Mvc;
  3. namespace WebApplication2.Controllers {
  4. [Route("api/[controller]")]
  5. [ApiController]
  6. public class TestController : ControllerBase {
  7. [HttpGet("t1")]
  8. public string t1() {
  9. return "成功测试";
  10. }
  11. }
  12. }

:::success

  1. API控制器命名以Controller结尾
  2. API控制器继承ControllerBase
  3. 在类上面有两个特性
    1. [ApiController]表示这个类是一个Api接口
    2. [Route("api/[controller]")]表示这个控制器的路由地址。里面的[controller]表示控制器的名字Test,不区分大小写。想要[controller]起作用,需要app.MapControllers();
  4. 在一个Controller里面可以有多个方法,每个方法才是一个具体的接口,方法上面的[HttpGet]表示请求类型
  5. 发送GET请求访问这个接口:http://localhost:5292/api/test/t1 ::: ```csharp using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc;

namespace WebApplication2.Controllers { [Route(“aaa”)] [ApiController] public class TestController : ControllerBase { [HttpGet] public string t1() { return “t1”; } [HttpPost] public string t2() { return “t2”; } [HttpPut] public string t3() { return “t3”; } [HttpDelete] public string t4() { return “t4”; } } }

  1. 如果像这样,每一种http方法都只有一个,且没有带具体的路由。直接用对应的http方法访问这个控制器就行了,比如我要访问t3(),发送PUT请求:http://localhost:5292/aaa。<br />这种做法不推荐,如果有两个同样方法的请求自动识别就不行了。
  2. :::success
  3. 这种情况就必须带方法的路径了,如果方法上没有在特性里面写路径。<br />需要在控制器里面写统一的方法路径`[Route("api/[controller]/[action]")]`。<br />访问接口的时候`[controller]`填控制器的名,`[action]`填方法名。这两个东西需要配置`app.MapControllers();`才有用。<br />比如发送POST请求:http://localhost:5292/api/test/t2
  4. :::
  5. ```csharp
  6. using Microsoft.AspNetCore.Http;
  7. using Microsoft.AspNetCore.Mvc;
  8. namespace WebApplication2.Controllers {
  9. [Route("test")]
  10. [ApiController]
  11. public class TestController : ControllerBase {
  12. [HttpGet("gett1")]
  13. public string t1() {
  14. return "t1";
  15. }
  16. [Route("postt2")]
  17. [HttpPost]
  18. public string t2() {
  19. return "t2";
  20. }
  21. }
  22. }

方法路由有两种写法,都可以。

接收参数

Query参数

基础类型接收

通过GET 的url传过来的参数。可以用这种基础类型一个一个接收

  1. [HttpGet("gett1")]
  2. public string t1(string name,int age,double money) {
  3. Console.WriteLine(name+age+money);
  4. return "t1";
  5. }

image.png
能获取值
image.png

实体类型接收

如果有很多参数,可以用一个实体类型接收。
这个实体类型前面需要加上特性[FromQuery]

  1. [HttpGet("gett1")]
  2. public string t1([FromQuery]TestData data) {
  3. return "t1";
  4. }

image.png

关于[FromQuery]等特性

还有这么多,顾名思义

  • FromBody:来自请求体,类似发送json数据的请求
  • FromForm:来自表单数据
  • FromHeader:来自请求头
  • FromRoute:来自路由
  • FromServices:没用过,应该是来自服务端

所以需要映射成实体对象的参数们,看参数的位置就行。
image.png

JSON参数

Json对象一般是请求体传递的,参数用实体对象接收的时候,默认就是[FromBody],可以省略

  1. [HttpPost("postt1")]
  2. public string t1(TestData data) {
  3. return "t1";
  4. }

image.png
image.png
数组也可以这么传递,本质还是json
image.png
image.png

Form参数

实体类型接收

  1. [HttpPost("postt1")]
  2. public string t1([FromForm]TestData data) {
  3. return "t1";
  4. }

image.png
image.png

基础类型接收

可以写多个参数,每个参数都带有[FromForm]特性。但是传递Json的[FromBody]不可以这么操作

  1. [HttpPost("postt1")]
  2. public string t1([FromForm]string name, [FromForm] int age, [FromForm]double money) {
  3. return "t1";
  4. }

image.png

Path参数

实体类型接收

  1. [HttpGet("gett1/{name}/{age}/{money}")]
  2. public string t1([FromRoute]TestData data) {
  3. return "t1";
  4. }

image.png
image.png

基础类型接收

可以写多个参数,每个参数都带有[FromForm]特性。

  1. [HttpGet("gett1/{name}/{age}/{money}")]
  2. public string t1([FromRoute]string name, [FromRoute]int age, [FromRoute]double money) {
  3. return "t1";
  4. }

image.png

Header参数

Header不能用实体来接收

  1. [HttpGet("gett1")]
  2. public string t1([FromHeader]string key, [FromHeader]string des) {
  3. return "t1";
  4. }

image.png
image.png

混合参数

发送请求时,全部位置的参数都带一点

  1. [HttpPost("postt1/{index}")]
  2. public string t1([FromBody]TestData data,[FromRoute]int index,[FromHeader]string key, [FromHeader]string des) {
  3. return "t1";
  4. }

image.png

dynamic接收一切Json参数

如果经常用实体接收参数,接口多了创建的参数就多了。干脆全部接口都统一用dynamic来接收。一统天下。

  1. [HttpPost("postt1")]
  2. public string t1(dynamic data) {
  3. return "t1";
  4. }

image.png :::danger dynamic可以用来接收请求体的数据,即[FromBody] :::

返回内容

响应结果中默认返回值为IActionResult,我们可以再Action返回基本数据类型、实体对象、视图等多种数据,这些结果都被封装在IActionResult中,对于不同的返回结果mvc框架提供了多种类型结果实现了此接口

动作类型 行为 结果
EmptyResult 如果Action方法返回类型为void,或者返回值为Null,最终生成的就是一个EmptyResult对象
ContentResult Content(string) 返回一串字符串
FileContentResult : FileResult File(byte[] fileContents, string contentType, string fileDownloadName) 由于FileContentResult是根据字节数组创建的,当我们需要动态生成响应文件内容(而不是从物理文件中读取)时,FileContentResult是一个不错的选择
FilePathResult : FileResult File(string fileName, string contentType, string fileDownloadName) 响应文件的路径通过只读属性FileName表示,该属性在构造函数中被初始化。在实现的WriteFile方法中,FilePathResult直接将文件路径作为参数调用当前HttpResponse的TransmitFile实现了针对文件内容的响应
FileStreamResult : FileResult File(Stream fileStream, string contentType, string fileDownloadName) 在实现的WriteFile方法中,FileStreamResult通过指定的文件流读取文件内容,并最终调用当前HttpResponse的OutputStream属性的Write方法将读取的内容写入当前HTTP响应的输出流中
JsonResult Json(Object) 返回Json格式数据
RedirectToResult Redirect(Url) RedirectToAction(“Index”, “Home”, new { id = “100”, name = “liu” }); / RedirectPermanent(Url) Redirect/RedirectPermanent方法用于创建重定向到指定URL的RedirectResult(302:301) ; RedirectToAction/RedirectToActionPermanent用于创建重定向到指定的目标Action的RedirectResult/RedirectToRouteResult
RedirectToRouteResult RedirectToRoute/RedirectToRoutePermanen RedirectToRoute(“Default”, new { controller = “Home”, action = “Index”}); RedirectToRoute / RedirectToRoutePermanent创建的RedirectResult/RedirectToRouteResult对象是针对注册的某个路由的
ViewResult View() 接收视图引擎的响应
PartialViewResult View() 接收分部视图引擎的响应
HttpUnauthorizedResult 抛出401错误
JavaScriptResult 返回javascript文件

上传文件

文件上传都是提交的表单形式

单文件上传

这样写法可以在表单里面上传,单文件

  1. [HttpPost("upload")]
  2. public string uploadFile([FromForm]IFormFile file1, [FromForm]IFormFile file2, [FromForm]IFormFile file3) {
  3. return "ok";
  4. }

image.png

多文件上传

  1. [HttpPost("upload")]
  2. public string uploadFile([FromForm]IFormFileCollection file1, [FromForm] IFormFileCollection file2) {
  3. return "ok";
  4. }

image.png

全部上传文件

  1. [HttpPost("upload")]
  2. public string uploadFile() {
  3. //通过Request.Form.Files可以获取传送过来的全部文件
  4. var formFile = Request.Form.Files[0];
  5. long fileSize = formFile.Length;
  6. string fileName=formFile.FileName;
  7. Stream stream = formFile.OpenReadStream();
  8. return "ok";
  9. }

下载文件

在浏览器输入地址后就会进行下载该文件

  1. [HttpGet("download/{fileName}")]
  2. public IActionResult downloadFile([FromRoute]string fileName) {
  3. string path = @"D:\安装包\yuanshen_setup_20220811050610.exe";
  4. return new FileStreamResult(new FileStream(path, FileMode.Open), "application/octet-stream");
  5. }