Controller和路由
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace WebApplication2.Controllers {
[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase {
[HttpGet("t1")]
public string t1() {
return "成功测试";
}
}
}
:::success
- API控制器命名以Controller结尾
- API控制器继承ControllerBase
- 在类上面有两个特性
[ApiController]
表示这个类是一个Api接口[Route("api/[controller]")]
表示这个控制器的路由地址。里面的[controller]
表示控制器的名字Test
,不区分大小写。想要[controller]
起作用,需要app.MapControllers();
- 在一个Controller里面可以有多个方法,每个方法才是一个具体的接口,方法上面的
[HttpGet]
表示请求类型 - 发送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”; } } }
如果像这样,每一种http方法都只有一个,且没有带具体的路由。直接用对应的http方法访问这个控制器就行了,比如我要访问t3(),发送PUT请求:http://localhost:5292/aaa。<br />这种做法不推荐,如果有两个同样方法的请求自动识别就不行了。
:::success
这种情况就必须带方法的路径了,如果方法上没有在特性里面写路径。<br />需要在控制器里面写统一的方法路径`[Route("api/[controller]/[action]")]`。<br />访问接口的时候`[controller]`填控制器的名,`[action]`填方法名。这两个东西需要配置`app.MapControllers();`才有用。<br />比如发送POST请求:http://localhost:5292/api/test/t2
:::
```csharp
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace WebApplication2.Controllers {
[Route("test")]
[ApiController]
public class TestController : ControllerBase {
[HttpGet("gett1")]
public string t1() {
return "t1";
}
[Route("postt2")]
[HttpPost]
public string t2() {
return "t2";
}
}
}
接收参数
Query参数
基础类型接收
通过GET 的url传过来的参数。可以用这种基础类型一个一个接收
[HttpGet("gett1")]
public string t1(string name,int age,double money) {
Console.WriteLine(name+age+money);
return "t1";
}
实体类型接收
如果有很多参数,可以用一个实体类型接收。
这个实体类型前面需要加上特性[FromQuery]
[HttpGet("gett1")]
public string t1([FromQuery]TestData data) {
return "t1";
}
关于[FromQuery]等特性
还有这么多,顾名思义
- FromBody:来自请求体,类似发送json数据的请求
- FromForm:来自表单数据
- FromHeader:来自请求头
- FromRoute:来自路由
- FromServices:没用过,应该是来自服务端
JSON参数
Json对象一般是请求体传递的,参数用实体对象接收的时候,默认就是[FromBody]
,可以省略
[HttpPost("postt1")]
public string t1(TestData data) {
return "t1";
}
Form参数
实体类型接收
[HttpPost("postt1")]
public string t1([FromForm]TestData data) {
return "t1";
}
基础类型接收
可以写多个参数,每个参数都带有[FromForm]
特性。但是传递Json的[FromBody]
不可以这么操作
[HttpPost("postt1")]
public string t1([FromForm]string name, [FromForm] int age, [FromForm]double money) {
return "t1";
}
Path参数
实体类型接收
[HttpGet("gett1/{name}/{age}/{money}")]
public string t1([FromRoute]TestData data) {
return "t1";
}
基础类型接收
可以写多个参数,每个参数都带有[FromForm]
特性。
[HttpGet("gett1/{name}/{age}/{money}")]
public string t1([FromRoute]string name, [FromRoute]int age, [FromRoute]double money) {
return "t1";
}
Header参数
Header不能用实体来接收
[HttpGet("gett1")]
public string t1([FromHeader]string key, [FromHeader]string des) {
return "t1";
}
混合参数
发送请求时,全部位置的参数都带一点
[HttpPost("postt1/{index}")]
public string t1([FromBody]TestData data,[FromRoute]int index,[FromHeader]string key, [FromHeader]string des) {
return "t1";
}
dynamic接收一切Json参数
如果经常用实体接收参数,接口多了创建的参数就多了。干脆全部接口都统一用dynamic
来接收。一统天下。
[HttpPost("postt1")]
public string t1(dynamic data) {
return "t1";
}
:::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文件 |
上传文件
单文件上传
这样写法可以在表单里面上传,单文件
[HttpPost("upload")]
public string uploadFile([FromForm]IFormFile file1, [FromForm]IFormFile file2, [FromForm]IFormFile file3) {
return "ok";
}
多文件上传
[HttpPost("upload")]
public string uploadFile([FromForm]IFormFileCollection file1, [FromForm] IFormFileCollection file2) {
return "ok";
}
全部上传文件
[HttpPost("upload")]
public string uploadFile() {
//通过Request.Form.Files可以获取传送过来的全部文件
var formFile = Request.Form.Files[0];
long fileSize = formFile.Length;
string fileName=formFile.FileName;
Stream stream = formFile.OpenReadStream();
return "ok";
}
下载文件
在浏览器输入地址后就会进行下载该文件
[HttpGet("download/{fileName}")]
public IActionResult downloadFile([FromRoute]string fileName) {
string path = @"D:\安装包\yuanshen_setup_20220811050610.exe";
return new FileStreamResult(new FileStream(path, FileMode.Open), "application/octet-stream");
}