Part4-16 ASP.NET Core Web API 控制器及返回值
ControllerBase VS COntroller
- ControllerBase与Controller, MVC 继承自 Controller, 增加了MVC View等功能 , API是直接继承ControllerBase;
- 控制器类可以不显式地继承自任何类。
Action方法的异步
- Action方法既可以同步也可以异步。
- 异步Action方法的名字一般不需要以Async结尾。
- Web API中Action方法的返回值如果是普通数据类型,那么返回值就会默认被序列化为Json格式。
- Web API中的Action方法的返回值同样支持IActionResult类型,不包含类型信息,因此Swagger等无法推断出类型,所以推荐用ActionResult<T>,它支持类型转换,从而用起来更简单。对于有可能返回报错信息的,可使用ActionResult<T>。
[HttpGet]
public ActionResult<Person> GetPerson(int id)
{
if (id <= 0)
return BadRequest("id必须是正数");
else if (id == 1)
return new Person(1, "chaoqiang", 18);//如果使用ActionResult<T>,就可以自动转换Person
//return Ok(person);//如果使用ActionResult 需要Ok转换一下
else if (id == 2)
return new Person(2, "superman", 8);
else
return NotFound(“人员不存在”);//自定义消息也重要
}
Part4-17 ASP.NET Core Web API Action方法参数
捕捉URL占位符
- 在[HttpGet]、[HttpPost]等中使用占位符,比如{schoolName},捕捉路径中的内容,从而供Action方法的参数使用。
- /Students/GetAll/school/MIT/class/A001
- [HttpGet(“school/{schoolName}/class/{classNo}”)]
- 捕捉的值会被自动赋值给Action中同名的参数;如果名字不一致,可以用[FromRoute(Name=”名字”)]
- 演示混用。
捕捉QUERYSTRING的值
- 使用[FromQuery]来获取QueryString中的值。如果名字一致,只要为参数添加[FromQuery]即可;而如果名字不一致,[FromQuery(Name = 名字)]。
- QueryString和Route可以混用。
[HttpGet("{i1}/{i2}")]
public int Plus(int i1, int i2)
{
return i1 + i2;
}
[HttpGet("students/school/{schoolName}/class/{classNo}")]
public Person GetStudents(string schoolName, [FromRoute(Name ="classNo")]long classNum)
{
return new Person ( classNum + 6, schoolName + "的扛把子", 9 );
}
[HttpPost]
public int Save([FromQuery(Name ="aaa")]int i1, int i2)
{
return i1 + i2;
}
JSON报文体
- Web API的开发模式下,Json格式的请求体是主流。
- 只要声明一个模型类和Json请求的格式一致即可。
- 也是可以把从URL获取参数、从请求报文体获取数据等这些混合使用。
- [HttpPost(“classId/{classId}”)]
- public ActionResult<long> AddNew(long classId, StudentModel s)
- 一定要设定请求头中的Content-Type为application/json,而且数据必须是合法的json格式。
其他方式,Web API中很少用的方式:
- 从Content-Type为multipart/form-data的请求中获取数据的[FromForm]
- 从请求报文头中获取值的[FromHeader]。
[HttpPut("{id}")]
public string UpdatePerson([FromRoute(Name = "id")] int id, Person p1,[FromHeader(Name ="User-Agent")]string agent)
{
var a = agent;
return "更新" + id +"成功" + p1.Name +"agent:"+a;
}
Part4-18 前后端分离开发(1)
1、传统MVC开发模式:前后端的代码被放到同一个项目中,前端人员负责编写页面的模板,而后端开发人员负责编写控制器和模型的代码并且“套模板”。缺点:互相依赖;耦合性强;责任划分不清。
2、主流的“前后端分离” :前端开发人员和后端开发人员分别负责前端和后端代码的开发,各自在自己的项目中进行开发;后端人员只写Web API接口,页面由前端人员负责。
为什么“前后端分离” 更流行:需求变动越来越大、交付周期越来越短、多端支持。
优点:独立开发,不互相依赖;耦合性低;责任划分清晰;前后端分别部署,可以针对性运维(扩容等)
缺点:对团队的沟通能力要求更高,提前沟通好接口和通知接口变更;不利于SEO(可以用“服务器端渲染”SSR);对运维要求更高。
3、只有大项目才需要前后端分离吗?小项目也可以前后端分离。
后端登陆实例
Part4-19 前后端分离开发(2)
前端登陆实例
- 1、Web API做后端开发,不绑定前端技术,也支持其他客户端。
- 2、Vue搭建步骤:
- 1)安装Node.js
- 2)设定国内镜像 npm config set registry https://registry.npm.taobao.org
- 3)安装yarn:npm install -g yarn
- 4)创建Vue项目:yarn create @vitejs/app 项目名字
- 5)按照提示运行项目。
Part4-20 前后端分离开发(3)
1、在src文件夹下创建views文件夹。
2、安装ajax库axios,项目根目录:yarn add axios
3、在views文件夹下创建Login.vue文件
<template>
用户名: <input type="text" v-model="state.loginData.userName" />
密码:<input type="submit" value="登录" @click="loginSubmit"/>
<tr v-for="p in state.processes" :key="p.id">
<td>{{(p.workingSet64/1024)}}K</td>
</tr>
</template>
<script setup>
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;
if(!data.isOK)
const resp = await axios.post('https://localhost:44360/api/Login/Login',payload);
const data = resp.data;
state.processes = data.processes;
}
return {state,loginSubmit};
},
</script>
4、使用vue-router来做前端的页面路由。在前端的项目根目录执行:yarn add vue-router@4
5、在src下创建route文件夹,并且在route文件夹下创建index.js文件
import { createRouter,createWebHashHistory} from "vue-router";
import Test from "../views/Test.vue";
import Login from "../views/Login.vue";
const routes = [{path: "/", redirect: "/Test"},
{path: "/Test",name:"Test",component: Test},
{path: "/Login",name:"Login",component: Login}]
const router = createRouter({history: createWebHashHistory(),routes: routes});
export default router
6、编辑src/main.js,增加import router from ‘./route’以及use(router),修改main.js:
import { createApp } from 'vue'
import App from './App.vue'
import router from './route'
createApp(App).use(router).mount('#app’);
7、src/App.vue中增加指向Login视图的链接以及显示路由视图的<router-view/>
<template>
<div><router-link to="Login">Login</router-link></div><router-view />
</template>
CORS
1、跨域通讯的问题。解决方案:JSONP、前端代理后端请求、CORS等。
2、CORS原理:在服务器的响应报文头中通过access-control-allow-origin告诉浏览器允许跨域访问的域名。
3、在Program.cs的“var app=builder.Build()”这句代码之前注册
4、在Program.cs的app.UseHttpsRedirection()这句代码之前增加一行app.UseCors()
string[] urls = new[] { "http://localhost:3000" };
builder.Services.AddCors(options =>
options.AddDefaultPolicy(builder => builder.WithOrigins(urls)
.AllowAnyMethod().AllowAnyHeader().AllowCredentials()));
本文版权归个人技术分享站点所有,发布者:chaoqiang,转转请注明出处:https://www.zhengchaoqiang.com/1372.html