.Net Core WebAPI中,无论是get、post或其他类型的方法。简单类型的数据会默认从url中获取,复杂类型的数据(实体类、列表等)默认从body中获取。
可以通过[FromQuery]、[FromBody]、[FromForm]等属性,强制从某个地方获取数据。但如果一个实体类被设定了[FromBody],则实体类中属性设定的其它[FromQuery]之类的注解无效。
可以为实体类中的属性加上[BindRequired]注解,设定为必填,不能应用于方法参数。
可以为实体类中的属性加上[BindNever]注解,设定为不接受绑定,不能应用于方法参数。
RestFul
axios中针对RestFul有以下四种简化写法(方框内的表示非必填):
axios#get(url[, config])
axios#delete(url[, config])
axios#put(url[, data[, config]])
axios#post(url[, data[, config]])
get广泛用于查询,可通过url直接访问,无可替代
post和put基本一致,一般不使用put
delete在特殊场景下有使用
post中传递的数据放在data中
config的常用的配置如下:
{
headers: {'Content-Type': 'application/json'}, // 自定义请求头,一般无需配置或在全局配置
params: {// 放在url中的参数(post等方法也能配置)
ID: 12345
},
timeout: 1000,// 指定请求超时的毫秒数(0 表示无超时时间)
responseType: 'json', // 表示服务器响应的数据类型,默认json,可以是 'blob'(接收文件),'arraybuffer', 'document', 'json', 'text', 'stream'
}
数据查询-Get
Get查询,只需要注意使用[FromQuery]即可,以下为具体使用。
简单参数
针对简单类型的参数,只需要前后端名称一致即可。即使参数个数对不上也能访问到(需要注意int等的默认值)。
axios.get("GetMoreNormal", {
params: {
strVal: 'demo',
intVal: 123
}
});
[HttpGet, Route("GetMoreNormarl")]
public void GetMoreNormarl(string strVal, int intVal, bool boolVal)
{
}
列表
前加[FromQuery]即可
axios.get("GetMoreList", {
params: {
aaa: 'adsf',
listVal: ["list1", "bbb", "ccc"],
listVal2: ["list2", "bbb", "ccc"],
}
});
[HttpGet, Route("GetMoreList")]
public void GetMoreList([FromQuery] List<string> listVal,
[FromQuery] List<string> listVal2,
string aaa)
{
}
但需要注意.NerCore WEBAPI的接收方式。
axios发送列表数据时,会将参数名后面加[],导致传送的数据的key为listVal[],webapi默认不支持这种形式。
可通过配置paramsSerializer解决,一般在request拦截中添加以下代码解决,参考网站:
import qs from 'qs';
service.interceptors.request.use(
config => {
// ......其他逻辑代码
if (config.method === 'get') {
config.paramsSerializer = function(params) {
return qs.stringify(params, { arrayFormat: 'repeat' });
};
}
return config;
}
);
实体类
前加[FromQuery]即可。
axios.get("GetEntity", {
params: {
aaa: 'adsf',
strVal: 'demo',
intVal: 123,
boolVal: false,
listVal: this.list1,
arrVal: this.list2
}
});
[HttpGet, Route("GetEntity")]
public void GetEntity([FromQuery] DiyParam diyParam)
{
}
public class DiyParam
{
public string strVal { get; set; }
public int intVal { get; set; }
public bool boolVal { get; set; }
public List<string> listVal { get; set; }
public string[] arrVal { get; set; }
}
文件
文件不建议使用Get,请参考Post使用。
数据提交-Post、Delete
简单类型参数
简单类型参数不能通过[FromBody]获取到,至少axios不行。
有以下两种方式获取:
将参数通过url传送
那么为什么不直接用get呢?下面是一个场景:
你有某个文章的删除权限,其它人没有
某个人给你发了一个图片,点击事件是删除那个文章
在你登录的情况下,点击了那个图片
如果是Get方法,文章就被删掉了,Delete或Post就不会
// 可以发现,get和delete仅仅只是方法类型不同而已
this.axios.delete("PostOneNormal", {
params: {
strVal: 'aaa',
strVal2: 'bbb',
}
}
[HttpDelete, Route("PostOneNormal")]
public void PostOneNormarl(string strVal, string strVal2)
{
}
// post需要多加个{}
this.axios.post("PostOneNormal2",{}, {
params: {
strVal: 'xxx',
strVal2: 'bbb',
}
}
[HttpPost, Route("PostOneNormal2")]
public void PostOneNormarl(string strVal, string strVal2)
{
}
使用Form表单提交,通过[FromForm]获取
let formData = new FormData();
formData.set("aaa", "sdfasdf");
formData.set("bbb", "123");
this.axios.post("PostOneNormal", formData,{
headers: {
"Content-type": "multipart/form-data" // 修改内容类型
},
});
[HttpPost, Route("PostOneNormal")]
public void PostOneNormarl([FromForm]string aaa, [FromForm]int bbb)
{
}
列表
使用Body和Url传参时,会触发类型转换异常
使用表单传参时,发送的数据会变成字符串逗号隔开的形式。会使接到的列表只有一个元素,所有数据都在第一个位置里。
所以,无法单独接收列表
实体类
只需保证前端参数与实体类属性名称一致即可
文件
文件传输以multipart/form-data形式上传
此处以ElementUI的Upload组件为例:
<el-upload action="api/testUrl/PostUpload" :data="{aaa: 'aaa', listVal: ['aaa', 'bbb']}" :limit="1">
<el-button size="small" type="primary">点击上传</el-button>
</el-upload>
[HttpPost, Route("PostUpload")]
public void PostUpload([FromForm] IFormCollection formInfo, [FromForm] List<string> listVal, [FromForm] string aaa)
{
IFormFileCollection files = formInfo.Files;
var file = files[0]; // 得到文件
// 可以使用此方法获取其它参数,也可以通过[FromForm]从方法入参接收
formInfo.TryGetValue("aaa", out StringValues aaa2);
}
通过上面的代码可以发现,可以从formInfo中获取aaa,也可以从方法参数中定义[FromForm]获取。
注意:列表传过来会变成逗号隔开的形式
接收后台返回的文件
后台返回字节数组
前端设置responseType为blob接收
注意:不能使用Get方法
示例如下
axios.post(访问路径, {额外参数,键值形式}, {
responseType: 'blob'
}).then(res => {
if (res.status === 204) {
this.$notify.error("无数据,无法生成文件!");
} else if (res.status === 200) {
// 通过下面的方法使界面弹出下载框
const blob = new Blob([res.data]); //处理文档流
const fileName = "文件名";
const elink = document.createElement('a');
elink.download = fileName;
elink.style.display = 'none';
elink.href = URL.createObjectURL(blob);
document.body.appendChild(elink);
elink.click();
URL.revokeObjectURL(elink.href); // 释放URL 对象
document.body.removeChild(elink);
} else {
this.$notify.error(res.data);
}
});
[HttpPost, Route("GetFile")]
public ActionResult GetFile()
{
byte[] fileByte;
// 如果是内存流,可以直接读到字节数组
using (FileStream fs = new FileStream(@"F:\Desktop\SI.xlsx", FileMode.Open))
{
BinaryReader br = new BinaryReader(fs);
br.BaseStream.Seek(0, SeekOrigin.Begin); //将文件指针设置到文件开
fileByte = br.ReadBytes((int)br.BaseStream.Length); // 将流读
return File(fileByte, "application/octet-stream");
}
}
————————————————
版权声明:本文为CSDN博主「星潮汐」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lycz_tpself/article/details/108663443