控制器父类用哪个 控制器类都是继承自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);builder.Services.AddControllers(); 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();if (app.Environment.IsDevelopment()){ app.UseSwagger(); app.UseSwaggerUI(); } app.UseCors(); app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();