控制器父类用哪个

控制器类都是继承自ControllerBase,而ASP.NET Core MVC项目中的控制器类默认继承自Controller。Controller类继承自ControllerBase,Controller类在ControllerBase的基础上增加了和视图相关的方法,而Web API的接口不涉及视图,因此除非读者需要在同一个控制器中同时提供Web API和MVC的功能,否则Web API的控制器类继承自ControllerBase即可。

操作方法的异步、返回值、状态码

ACTION方法的异步

1.Action方法既可以同步也可以异步。
2.异步Action方法的名字一般不需要以Async结尾。
3.Web API中Action方法的返回值如果是普通数据类型,那么返回值就会默认被序列化为Json格式。
4.Web API中的Action方法的返回值同样支持IActionResult类型,不包含类型信息,因此Swagger等无法推断出类型,所以推荐用ActionResult<T>,它支持类型转换,从而用起来更简单。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[HttpGet]
public ActionResult<string> GetXIAN(int id)
{
if (id == 1)
{
return $"You are a good person";
}
else if (id == 2)
{
return $"You are a bad person";
}
else
{
return NotFound("Person not found");
}
}

Action方法参数

我们再给服务器端传递参数的时候,有URL、QueryString、请求报文体3种方式。

1.在[HttpGet]、[HttpPost]等中使用占位符,比如{schoolName},捕捉路径中的内容,从而供Action方法的参数使用。加入请求的路径为/Students/GetAll/school/MIT/class/A001[HttpGet(“school/{schoolName}/class/{classNo}”)]
2.捕捉的值会自动赋值给Action中同名的参数;如果名字不一致,可以用[FormRoute(Name=”名字”)]

1
2
3
4
5
[HttpGet("students/school/{schoolName}/class/{classNo}")]
public Person GetStudent(string schoolName, [FromRoute(Name ="classNo")]int classNum)
{
return new Person { Id = classNum + 6, Name = schoolName + "的扛把子" };
}

捕捉QUERYSTRING的值

1.使用[FromQuery]来获取QueryString中的值。如果名字一致,只要为参数添加[FromQuery]即可;而如果名字不一致,[FromQuery(Name=名字)]。
2.QueryString和Route可以混用。

1
2
3
4
public ActionResult<Person[]> GetAll([FromQuery] string paueNum, [FromQuery(Name = "pSize")] int pageSize)
{
return new Person[] { pageSize == 0 ? new Person { Id = 1, Name = "YOUXIANYU", ChildenName = new string[] { "aaa", "bbb" } } : new Person { Id = 2, Name = "YOUXIANYU", ChildenName = new string[] { "aaa", "bbb" } } };
}

JSON报文体

1.Web API的开发模式下,Json格式的请求提是主流。
2.只要声明一个模型类和Json请求的格式一致即可。
3.也是可以把从URL获取参数、从请求报文体获取数据等这些混合使用。

1
2
[HttpPost("classId/{classId}")]
public ActionResult<long> AddNew(long classId,StudentModel s)

4.一定要设定请求头中的Content-Type为application/json,而且数据必须是合法的json格式。

表单请求:从Content-Type为multipart/form-data的请求中获取数据的[FromForm]

从请求报文头中获取值的[FromHeader]。

ASP.NET Core Web API前后端分离开发

开发Web API 后端接口

首先,我们新建一个ASP.NET Core Web 然后在项目中创建一个控制器类LoginController。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
[Route("api/[controller]/[action]")]
[ApiController]
public class LoginValuesController : ControllerBase
{
[HttpPost]
public ActionResult<LoginResponse> Login(LoginRequest req)
{
if(req is ("YOUXIANYU", "123456"))
{
var items = Process.GetProcesses()
.Select(p => new ProcessInfo(p.Id, p.ProcessName, p.WorkingSet64));
return new LoginResponse(true, items.ToArray());
}
else
{
return new LoginResponse(false, null);
}
}
}
}

Login方法用来判断请求的用户名、密码是否正确,如果正确的话,服务器端会把当前计算机上运行的所有进程信息返回给客户端,返回的信息包括进程ID、进程名(ProcessName)和内存占用(WorkingSet64)。

其中LoginResult、LoginRequest、ProcessInfo类的定义。

1
2
3
public record LoginRequest(string UserName,string Password);
public record ProcessInfo(long Id,string Name,long WorkingSet);
public record LoginResponse(bool OK,ProcessInfo[]? ProcessInfos);

LoginResult类的IsOK属性表示请求的用户名和密码是否正确,如果正确,服务器端的进程信息会被设置到Processes属性上:LoginRequest类代表请求的参数信息,其中的UserName代表用户名,Password代表密码:ProcessInfo类代表进程信息,其中的Id代表进程ID,ProccessName代表进程名,WorkingSet64代表为进程分配的物理内存量。
在Swagger页面上测试一下Login方法。如果我们通过请求报文体设置的用户名、密码错误的话,服务器端的响应如图。

搭建前端

1.在src文件夹下创建views文件夹。
2.安装axios. npm i axios
3.在views文件夹下创建Login.vue文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<template>
用户名:<input type="text" v-model="state.loginData.userName"/>
密码:<input type="password" v-model="state.loginData.password"/>
<input type="submit" value="登录" @click="loginSubmit"/>
<ul>
<li v-for="p in state.processes" :key="p.id">{{p.id}}{{ p.processName}}{{p.workingSet64}}
</li>
</ul>
</template>

<script>
import axios from 'axios';
import { reactive, onMounted } from 'vue'
export default {
name: 'Login',
setup() {
const state = reactive({ loginData: {}, processes: [] });
const loginSubmit = async() => {
const payload = state.loginData;
const resp = await axios.post('https://localhost:7105/api/Login/Login', payload);
const data = resp.data;
if (!data.isOK) {
alert("登录失败");
return;
}
state.processes = data.processes;
}
return {state,loginSubmit}
}
}
onMounted(() => {
alert(state);
})
</script>

4.使用vue-router来做前端的页面路由。在前端的项目根目录执行:
npm run-router
5.在src下创建route文件夹,并且在route文件夹下创建index.js文件

1
2
3
4
5
6
7
8
9
import { createRouter, createWebHashHistory } from "vue-router";
import Login from "@/view/Login.vue";

const routes = [{
path: "/", redirect: "/Login"
}, { path: "/Login", name: "Login", coponent: Login }]

const router = createRouter({ history: createWebHashHistory(), routes: routes });
export default router;

6.编辑src/main.js,增加import router from ‘./route’ 以及use(router),修改main.js:

1
2
3
4
5
6
7
import './assets/main.css'

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

createApp(App).use(router).mount('#app')

7.src/App.vue中增加指定Login视图的链接以及显示路由视图的<router-view/>

1
2
3
4
5
6
7
8
9
10
11
12
13
<script setup>
// import HelloWorld from './components/HelloWorld.vue'
// import TheWelcome from './components/TheWelcome.vue'
import Login from './view/Login.vue';
import { RouterView,RouterLink} from 'vue-router';
</script>

<template>
<div>
<router-link to="/Login">Login</router-link><router-view/>
<login/>
</div>
</template>

CORS

1.跨域通讯的问题。解决方案:JSONP、前端代理后端请求、CORS等。
2.CORS原理:在服务器的响应报文头中通过access-control-allow-orign告诉浏览器允许跨域访问的域名。
3.在Program.cs的“var app=builder.Build()”这句代码之前注册
4.在Program.cs的app.UserHttpsRedirection()这句代码之前增加一行app.UseCors()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddCors(opt =>
{
opt.AddDefaultPolicy(b =>
{
b.WithOrigins(new string[] { "http://localhost:5173" })
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();
});
});

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}


app.UseCors();
app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();