【WebApi系列】详解WebApi如何传递参数

摘要:
请按照图中的步骤查看Values控制器是如何成为一个1publicclassValuesController的:这两个类别集中在Get和Post中(Put是Get和Post的组合,只需研究Get和Post方法的参数传递即可。我们的文章基于Get和Post法的参数传递。

原文地址:https://www.cnblogs.com/wangjiming/p/8378108.html

一 概述

一般地,我们在研究一个问题时,常规的思路是为该问题建模;我们在研究相似问题时,常规思路是找出这些问题的共性和异性。基于该思路,我们如何研究WebApi参数传递问题呢?

首先,从参数本身来说,种类较为多(如int,double,float,string,array,Object等),且有些类型较为复杂(如值类型和引用类型的机制等);

其次,从基于WebApi的Http请求方法来说,种类多且不尽相同(如Get,post,Delete,put,head等),在上一篇文章 :【WebApi系列】浅谈HTTP在WebApi开发中的运用  中,我们简要描述了Http请求的20个方法;

..........

如此复杂且不尽相同,关于WebApi参数传递,我们该选择什么作为切入点来研究呢?基于我们上面提到的研究思路,我们想到了.NET Framework框架,那么,我们来看看基于.NET Framework框架的的WebApi

模板是怎样的呢?

请按图中步骤操作

【WebApi系列】详解WebApi如何传递参数第1张

我们来看看Values控制器是怎样的

复制代码
 1  public class ValuesController : ApiController
 2     {
 3         // GET api/values
 4         public IEnumerable<string> Get()
 5         {
 6             return new string[] { "value1", "value2" };
 7         }
 8 
 9         // GET api/values/5
10         public string Get(int id)
11         {
12             return "value";
13         }
14 
15         // POST api/values
16         public void Post([FromBody]string value)
17         {
18         }
19 
20         // PUT api/values/5
21         public void Put(int id, [FromBody]string value)
22         {
23         }
24 
25         // DELETE api/values/5
26         public void Delete(int id)
27         {
28         }
29     }
复制代码

从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"}
            })
        })           
   })
复制代码

Result

【WebApi系列】详解WebApi如何传递参数第6张

 总结

(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均一致

【WebApi系列】详解WebApi如何传递参数第7张

(3)Get传递参数本质是url字符串拼接,Request-Head头部传递,Request-Body中不能传递(这是与Post方法的本质区别),我们举两个例子

例子1:我们将形参添加[FromBody]属性后,值传递不进去

【WebApi系列】详解WebApi如何传递参数第8张

例子2:我们用PostMan来测试,发现PostMan中,Get方法参数Body为灰色,是不能选中的

 【WebApi系列】详解WebApi如何传递参数第9张

1.2  方法含有多个形参(参数传得进去)

复制代码
$(document).ready(function () {
   $("#FindProdcutDetail").click(function () {
      $.ajax({
               type: "Get",
               url: "/api/Default/GetProductDetails",
               data: { "ProductCode": "JX80869","ProductName":"YaGao"}
            })
        })
  })
复制代码

result

【WebApi系列】详解WebApi如何传递参数第12张

2   实体对象类型(参数传不进去)


 model

复制代码
 1  public class ProductDetail
 2     {
 3         //产品编码
 4         [Required]
 5         public string ProductCode { get; set; }
 6         //产品名称
 7         [Required]
 8         public string ProductName { get; set; }
 9         //产品价格
10         [Required]
11         public double  ProductPrice{ get; set; }
12     }
复制代码

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:

【WebApi系列】详解WebApi如何传递参数第17张

 分析

【WebApi系列】详解WebApi如何传递参数第18张

3   实体对象和基础数据类型混合(实体传不进去,基础数据能传递进去)


 ajax

复制代码
1 $(document).ready(function () {
2    $("#FindProdcutDetail").click(function () {
3        $.ajax({
4                 type: "Get",
5                 url: "/api/Default/GetProductDetails",
6                 data: { "_productDetail": "ObjectEntity","ProductName":"YaGao"}
7              })
8         })
9     })
复制代码

 result

【WebApi系列】详解WebApi如何传递参数第21张

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

【WebApi系列】详解WebApi如何传递参数第24张

 分析:主要原因是路由规则,路由从url里面取参数与aciton参数匹配,直到匹配满足为止,具体详细深入内容,在【WebApi系列】路由章节分析。

【WebApi系列】详解WebApi如何传递参数第25张

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

【WebApi系列】详解WebApi如何传递参数第28张

6  Get规范化


 关于Get类型规范化,应注意两点,避免不必要的错误或异常:(1)方法的命名尽量采用:“Get+方法名”的形式 (2)在每个方法上加上特性[HttpGet]。

【WebApi系列】详解WebApi如何传递参数第29张

例子:我们去掉[HttpGet]特性和方法前的Get,看看情况什么怎样的

ajax

复制代码
$(document).ready(function () {
    $("#FindProdcutDetail").click(function () {
        $.ajax({
                 type: "Get",
                 url: "/api/Default/ProductDetails",
                 data: {"ProductCode": "JX00034 "}
             })
         })
    })
复制代码

Controller

复制代码
1 public class DefaultController : ApiController
2     {
3         4         //[HttpGet]
5         public string ProductDetails(string ProductCode)
6         {
7             return "values";
8         }
9     }
复制代码

 Result

【WebApi系列】详解WebApi如何传递参数第34张

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

【WebApi系列】详解WebApi如何传递参数第37张

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

【WebApi系列】详解WebApi如何传递参数第40张

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

【WebApi系列】详解WebApi如何传递参数第41张

result

【WebApi系列】详解WebApi如何传递参数第42张

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

【WebApi系列】详解WebApi如何传递参数第45张

Googel Chrome查看

【WebApi系列】详解WebApi如何传递参数第46张

2 实体作为参数传递


 ajax

复制代码
$(document).ready(function () {
   $("#FindProdcutDetail").click(function () {
      $.ajax({
               type: "Post",
               url: "/api/Default/PostParamToProducts",
               data: { "ProductCode": "JX00036","ProductName":"YaGao","ProductPrice":20.5}
            })
        })
    })
复制代码

result

【WebApi系列】详解WebApi如何传递参数第49张

我们用Googel  Chrome看看

【WebApi系列】详解WebApi如何传递参数第50张

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

【WebApi系列】详解WebApi如何传递参数第53张

Google Chrome 查看

【WebApi系列】详解WebApi如何传递参数第54张

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

【WebApi系列】详解WebApi如何传递参数第57张

我们用Google Chrome看看

【WebApi系列】详解WebApi如何传递参数第58张

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.关于如何设计一个良好的接口,在文章中,我们触及了一下,但未研究,会在后续的文章中单独分析;

免责声明:文章转载自《【WebApi系列】详解WebApi如何传递参数》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Linux常用命令(1)谈谈对redux的认识下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

HTML5--》点击显示隐藏内容

<details>浏览器支持比较差,可以用JavaScript实现这种功能。 1 <!doctype html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>js点击显示隐藏内容</title> 6 &...

iTween研究院之学习笔记Move移动篇

         最近项目中需要加入一些模型移动的小动画,学习过程中发现了iTween这个类库。它主要的功能就是处理模型从起始点到结束点之间运动的轨迹。(移动,旋转,音频,路径,摄像机等)它是一个开源的项目并且完全免费,它们的官网在这里 http://itween.pixelplacement.com/index.php 打开网之后点击右上角Get iTw...

浅析前端常见文件下载的9种场景:Blob基础知识/组成/Blob URL、a标签下载、showSaveFilePicker API下载(兼容性差)、FileSaver.js库下载、Zip下载(JSZip库)、附件形式下载(设置Content-Disposition)、base64格式下载(需转为blob)、分块传输下载、HTTP范围请求下载、大文件分块并行下载

  一般在我们工作中,主要会涉及到 9 种文件下载的场景,每一种场景背后都使用不同的技术,其中也有很多细节需要我们额外注意。   在浏览器端处理文件的时候,我们经常会用到 Blob 。比如图片本地预览、图片压缩、大文件分块上传及文件下载。在浏览器端文件下载的场景中,比如我们今天要讲到的 a 标签下载、showSaveFilePicker API 下载、Z...

rocketmq 修改broker和namesrv默认设置的堆内存大小

broker的堆内存的启动脚本在     C:UsersAdministratorDesktop ocketmq-all-4.7.1-source-releasedistributionin文件夹下面  可以看到 其堆内存为8g 可以根据实际情况对其进行调整 JAVA_OPT="${JAVA_OPT} -server -Xms1g -Xmx1g -Xmn...

Visual Studio中你所不知道的智能感知

在Visual Studio中的智能感知,相信大家都用过。summary,param,returns这几个相信很多人都用过的吧。那么field,value等等这些呢。 首先在Visual Studio中支持的JavaScript智能感知有以下6种 summary 用于方法和主体内容 param 用于方法的参数 field 用于类的属性 va...

解决 java命令行运行class文件时报“错误:找不到或无法加载主类”

问题描述: 今天准备开始复习一下jvm参数,在 perfma 社区里正好有这么一个小课程:https://club.perfma.com/course 从第一节开始复习时,大佬在课后留了一个问题,所以最好自己在java命令行中运行验证一下。结果没想到就碰到了“错误:找不到或无法加载主类”这个问题。 程序都没运行起来,怎么验证jvm参数啊??? 于是前后耗时...