WebApi如何传递参数
一 概述
一般地,我们在研究一个问题时,常规的思路是为该问题建模;我们在研究相似问题时,常规思路是找出这些问题的共性和异性。基于该思路,我们如何研究WebApi参数传递问题呢?
首先,从参数本身来说,种类较为多(如int,double,float,string,array,Object等),且有些类型较为复杂(如值类型和引用类型的机制等);
其次,从基于WebApi的Http请求方法来说,种类多且不尽相同(如Get,post,Delete,put,head等)
如此复杂且不尽相同,关于WebApi参数传递,我们该选择什么作为切入点来研究呢?基于我们上面提到的研究思路,我们想到了.NET Framework框架,那么,我们来看看基于.NET Framework框架的的WebApi
模板是怎样的呢?
请按图中步骤操作
我们来看看Values控制器是怎样的
public class ValuesController : ApiController
{
// GET api/values
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
} // GET api/values/5
public string Get(int id)
{
return "value";
} // POST api/values
public void Post([FromBody]string value)
{
} // PUT api/values/5
public void Put(int id, [FromBody]string value)
{
} // DELETE api/values/5
public void Delete(int id)
{
}
}
从Values控制器,我们不难得出如下几个结论:
(1)WebApi常规方法为四个:Get,Post,Put和Delete;
(2)四种方法的参数可归结为两大类:url传递(Request-url)和Body(Request-body)传递;
(3)基于(2),我们将四种方法的参数传递归为两大类,而这两大类又集中在Get和Post中体现了(Put是Get和Post的组合,Delete与Get类似);
其实,分析到现在,我们很容易找得到了研究WebApi参数传递的切入点?研究Get和Post方法参数传递即可。是的,没错,我们本篇文章就是基于Get和Post方法的参数传递,前者对应Request-url,后者对应Reqeust-Body。
二 Get
1 基础数据类型
1.1 方法只含一个形参(参数传得进去)
ajax
$(document).ready(function () {
$("#FindProdcutDetail").click(function () {
$.ajax({
type: "Get",
//url: "/api/Default/GetProductDetails?ProductCode=JX80869"
url: "/api/Default/GetProductDetails",
data: { "ProductCode":"JX80869"}
})
})
})
总结
(1)当Get方法形参为一个且为基本数据类型时,Get方法能接受外部传递的值
(2)Get传值的本质是通过url字符串拼接,如上两两种url形式的传递的结果都是一样
url形式1
url: "/api/Default/GetProductDetails?ProductCode=JX80869"
url形式2
url: "/api/Default/GetProductDetails",
data: { "ProductCode":"JX80869"}
我们用Goole Chrome来看看结果,发现url形式1和url形式2均一致
(3)Get传递参数本质是url字符串拼接,Request-Head头部传递,Request-Body中不能传递(这是与Post方法的本质区别),我们举两个例子
例子1:我们将形参添加[FromBody]属性后,值传递不进去
例子2:我们用PostMan来测试,发现PostMan中,Get方法参数Body为灰色,是不能选中的
1.2 方法含有多个形参(参数传得进去)
$(document).ready(function () {
$("#FindProdcutDetail").click(function () {
$.ajax({
type: "Get",
url: "/api/Default/GetProductDetails",
data: { "ProductCode": "JX80869","ProductName":"YaGao"}
})
})
})
result
2 实体对象类型(参数传不进去)
model
public class ProductDetail
{
//产品编码
[Required]
public string ProductCode { get; set; }
//产品名称
[Required]
public string ProductName { get; set; }
//产品价格
[Required]
public double ProductPrice{ get; set; }
}
ajax
$(document).ready(function () {
var productDetail = { "ProductName": "YaGao", "ProductCode": "JX80869", "ProductPrice": 40.5};
$("#FindProdcutDetail").click(function () {
$.ajax({
type: "Get",
url: "/api/Default/ProductDetails",
data: productDetail
})
})
})
result:
分析
3 实体对象和基础数据类型混合(实体传不进去,基础数据能传递进去)
ajax
$(document).ready(function () {
$("#FindProdcutDetail").click(function () {
$.ajax({
type: "Get",
url: "/api/Default/GetProductDetails",
data: { "_productDetail": "ObjectEntity","ProductName":"YaGao"}
})
})
})
result
4 最小满足原则(参数传得进去)
所谓“最小满足原则”,指外部参数必须至少满足被调用方法的形参(形参个数,形参类型和形参名字),换句话说,被调用方法具有的形参,外部参数必须传递进来,被调用方法没有
的形参,外部参数传递与否都可以,否则将会产生状态码404错误,用数学集合的思路来理解的话,被调用方法的形参相当于外部参数的子集。如下例子,我们举一个真子集的例子,
即外部传递参数的个数大于被调方法的的形参个数。
Ajax
$(document).ready(function () {
$("#FindProdcutDetail").click(function () {
$.ajax({
type: "Get",
url: "/api/Default/GetProductDetails",
data: {"ProductCode": "JX00034", "ProductName": "YaGao", "ProductPrice": 20.5, "PrudcutType": "Daily Necessities"}
})
})
})
result
分析:主要原因是路由规则,路由从url里面取参数与aciton参数匹配,直到匹配满足为止
5 url长度限制
url参数长度是有一定限制的,当超过一定长度,会报404错误
ajax
$(document).ready(function () {
$("#FindProdcutDetail").click(function () {
$.ajax({
type: "Get",
url: "/api/Default/GetProductDetails",
data: {
"ProductCode":
"JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
"JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
"JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
"JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
"JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
"JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
"JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
"JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
"JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
"JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
"JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
"JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
"JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
"JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
"JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
"JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
"JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
"JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
"JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
"JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
"JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
"JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
"JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
"JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
"JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
"JX00034xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
})
})
})
result
6 Get规范化
关于Get类型规范化,应注意两点,避免不必要的错误或异常:(1)方法的命名尽量采用:“Get+方法名”的形式 (2)在每个方法上加上特性[HttpGet]。
例子:我们去掉[HttpGet]特性和方法前的Get,看看情况什么怎样的
ajax
$(document).ready(function () {
$("#FindProdcutDetail").click(function () {
$.ajax({
type: "Get",
url: "/api/Default/ProductDetails",
data: {"ProductCode": "JX00034 "}
})
})
})
Controller
public class DefaultController : ApiController
{
//[HttpGet]
public string ProductDetails(string ProductCode)
{
return "values";
}
}
Result
7 关于实体作为参数传递的拓展
7.1 借助[FromUri]特性传递实体
ajax
$(document).ready(function () {
var GetEntityParam = { "ProductName": "YaGao", "ProductCode": "JX80869", "ProductPrice": 40.5};
$("#FindProdcutDetail").click(function () {
$.ajax({
type: "Get",
url: "/api/Default/ProductDetails",
data: GetEntityParam
})
})
})
result
7.2 系列化与反系列化传递实体
ajax
$(document).ready(function () {
$("#FindProdcutDetail").click(function () {
$.ajax({
type: "Get",
url: "/api/Default/ProductDetails",
data: { "productDetail": JSON.stringify({ "ProductName": "YaGao", "ProductCode": "JX80869", "ProductPrice": 40.5 }) }
})
})
})
result
8 小结
(1)Get参数传递的本质是url字符串拼接;
(2)url字符串长度受限制;
(3)Get参数传递在Http请求头部传递,而不支持Request-Body传递;
(4)Get类型的方法支持参数为基本类型,不支持实体类型;
(5)Get类型的方法命名,应尽量采用“Get+方法名”的命名方式,且习惯性地在方法前加上[HttpGet特性];
(6)实参与形参的匹配,遵循路由规则;
(7)Get对应DB的Select操作,从这一点来理解,就知道为什么Http不支持实体对象传递的合理性了,因为一般情况,我们都是通过简单的字段查询信息(对应基本类型),
如ID号,用户名等,而不会通过一个实体查询数据;
三 Post
1 基本数据类型传递
1.1 [FromBody]单个参数传递
ajax
result
1.2 dynamic单个参数传递
ajax
$(document).ready(function () {
$("#FindProdcutDetail").click(function () {
$.ajax({
type: "Post",
contentType: 'application/json',
url: "/api/Default/PostParamToProducts",
data: JSON.stringify({"ProductCode":"JX00039"})
})
})
})
result
Googel Chrome查看
2 实体作为参数传递
ajax
$(document).ready(function () {
$("#FindProdcutDetail").click(function () {
$.ajax({
type: "Post",
url: "/api/Default/PostParamToProducts",
data: { "ProductCode": "JX00036","ProductName":"YaGao","ProductPrice":20.5}
})
})
})
result
我们用Googel Chrome看看
3 实体集合作为参数传递
ajax
$(document).ready(function () {
var list_ProductDetail = [
{ "ProductCode": "JX00031", "ProductName": "ToothPaste", "ProductPrice": "20.5" },
{ "ProductCode": "JX00032", "ProductName": "ToothBrush ", "ProductPrice": "18.9" },
{ "ProductCode": "JX00033", "ProductName": "Pen", "ProductPrice": "199.9" },
{ "ProductCode": "JX00034", "ProductName": "computer", "ProductPrice": "15000.5" }
]
$("#FindProdcutDetail").click(function () {
$.ajax({
type: "Post",
contentType: 'application/json',
url: "/api/Default/PostParamToProducts",
data: JSON.stringify(list_ProductDetail)
})
})
})
result
4 数组作为参数传递
ajax
$(document).ready(function () {
var arr = ["a", "b", "c", "d"];
$("#FindProdcutDetail").click(function () {
$.ajax({
type: "Post",
contentType: 'application/json',
url: "/api/Default/PostParamToProducts",
data: JSON.stringify(arr)
})
})
})
Result
我们用Google Chrome看看
5 小结
(1)Post参数传递本事是在Request-Body内传递,而Get参数传递本质是url拼接;
(2)Post参数传递不是key/value形式,而Get参数是key/value形式;
(3)Post传递参数时,无论是单个参数还是对象,均借助[FromBody]特性(当然,某些情况去掉[FromBody]特性也可把值传递进去,但未了规范化,尽量加上该特性);
(4)Post没长度限制,而Get有长度限制(一般为1024b);
(5)Post相对Get,较安全;
(6)Post操作相当于DB的Insert操作;
四 总结
1.虽然HTTP请求方法有20多种,常用的大致为4种,即Get,Post,Put,Delete(当然,像Trace,Head等也常用);
2.Get,Post,Put,Delete分别对应DB的Select,Insert,Update和Delete操作;
3.WebApi参数类型,大致分为基本数据类类型和对象数据类型(当然你也可以理解为抽象数据类型);
4.研究WebApi参数传递,只需研究Get和Post即可,因为其他http方法参数传递基本都是有这两种组合而成(如Put有Get和Post组合而成),或者相似(如Delete与Get相似);
5.对于控制器方法,尽量参照规范格式写,如在相应控制器方法上加上对应的htt请求(Get对应[HttpGet],Post对应[HttpPost]),方法名尽量采用“Http请类型+方法名”格式(如Get请求,建议采用Get+MethodName;Post请求对应Post+MethodName);
6.WebApi参数请求,大致分为两大类型,即Request-url和Request-body;
7.文中我们还简要分析了Get和Post区别;
8.关于如何设计一个良好的接口,在文章中,我们触及了一下,但未研究,会在后续的文章中单独分析;
结束!
来源: Alan_beijing
WebApi如何传递参数的更多相关文章
- 【WebApi系列】详解WebApi如何传递参数
WebApi系列文章 [01]浅谈HTTP在WebApi开发中的运用 [02]聊聊WebApi体系结构 [03]详解WebApi参数的传递 [04]详解WebApi测试和PostMan [05]浅谈W ...
- WebAPI学习日记一:Ajax请求传递参数遇到的问题
首先,本人大学刚毕业,想把自己学习的一些东西记录下来,也是和大家分享,如有不对之处还请多加指正.声明:但凡是我博客里的文章均是本人实际操作遇到的例子,不会随便从网上拷贝或者转载,本着对自己和观众负责的 ...
- Ajax请求传递参数遇到的问题
想写个同类型的,代码未测. 什么是WebAPI?我的理解是WebAPI+JQuery(前端)基本上能完成Web MVC的功能,即:这么理解吧,WebAPI相当于Web MVC的后台部分. 接下来直接上 ...
- [置顶]
webapi token、参数签名是如何生成的
一个问题 在这里我想问大家一句,如果你向一个刚刚接触.net web后端程序开发的同学(别人刚刚也就学了webform的request,response,会提交表单的这种刚接触不久的同学),你怎么去解 ...
- webapi token、参数签名是如何生成的(转载)
API接口保障安全性原则:1.有调用者身份2.请求的唯一性3.请求的参数不能被篡改4.请求的有效时间 在刚接触接口开发时,可能脑子里压根就没有这个接口调用安全性的原则,但常识性的经验告诉我们,每一个请 ...
- Vue 给子组件传递参数
Vue 给子组件传递参数 首先看个例子吧 原文 html <div class="container" id="app"> <div clas ...
- [转] C++的引用传递、指针传递参数在java中的相应处理方法
原文出处:[http://blog.csdn.net/conowen/article/details/7420533] 首先要明白一点,java是没有指针这个概念的. 但是要实现C++的引用传递.指针 ...
- 记一次WinForm程序中主进程打开子进程并传递参数的操作过程(进程间传递参数)
目标:想在WinForm程序之间传递参数.以便子进程作出相应的处理. 一种错误的方法 父进程的主程序: ProcessStartInfo psi = new ProcessStartInfo(); p ...
- 在 Angularjs 中 ui-sref 和 $state.go 如何传递参数
1 ui-sref.$state.go 的区别 ui-sref 一般使用在 <a>...</a>: <a ui-sref="message-list" ...
随机推荐
- arcpy模块下的并行计算与大规模数据处理
一个多星期的时间,忍着胃痛一直在做GIS 540: Spatial Programming的课程项目,导致其他方面均毫无进展,可惜可惜.在这个过程当中临时抱佛脚学习了很多Python相关的其他内容,并 ...
- Python ( )、[ ]、{}的区别
python语言最常见的括号有三种,分别是:小括号( ).中括号[ ]和大括号也叫做花括号{ },分别用来代表不同的python基本内置数据类型. python中的小括号( ):代表tuple元组数据 ...
- https://lug.ustc.edu.cn/wiki/user/boj/linkers-and-loaders
https://lug.ustc.edu.cn/wiki/user/boj/linkers-and-loaders 程序员的自我修养——链接.装载与库
- TextFX Notepad++
textFx Notepad++ - 国内版 Bing https://cn.bing.com/search?FORM=U227DF&PC=U227&q=textFx+Notepad% ...
- Hive小文件处理
小文件是如何产生的: 动态分区插入数据的时候,会产生大量的小文件,从而导致map数量的暴增 数据源本身就包含有大量的小文件 reduce个数越多,生成的小文件也越多 小文件的危害: 从HIVE角度来看 ...
- ubuntu18.04安装docker和开通对外2375端口(方便portainer管理)
date: 2019-08-03 21:39:37 author: headsen chen apt-get install apt-transport-https ca-certificates ...
- typeScript模块<三>
/*模块 1 模块的的概念 2 模块导出的几种方法 1.export 导出声明 2.export 导出语句 3.export default 4.import导入模块 3 模块化封装上一讲的DB库 * ...
- Qt编写自定义控件67-通用无边框
一.前言 在之前的一篇文章中写过一个通用的移动控件,作用就是用来传入任意的widget控件,可以在父类容器中自由移动.本篇文章要写的是一个通用的无边框类,确切的说这不叫控件应该叫组件才对,控件是要看得 ...
- [转]Xmind 8 pro 软件破解版
链接地址:https://blog.csdn.net/qq_16093323/article/details/80967867 作者博客:http://www.carrotchou.blog/
- 内存运行PE文件
内存中运行文件 拿exe并在HxD或010中打开 - cntrl+a copy as C 粘贴到encrypt.cpp 编译并运行encrypt.cpp - 创建shellcode.txt 从shel ...