详解WebAPI 如何传递参数

一、概述


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


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


其次,从基于WebAPI的Http请求方法来说,种类多且不尽相同

(如Get,post,Delete,put,head等),在文章 《浅谈HTTP在WebAPI开发中的运用》,我们简要描述了Http请求的20个方法;


如此复杂且不尽相同,关于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"}

            })

        })           

   })


Result




总结


(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错误




result




6、Get规范化


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




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


$(document).ready(function () {

    $("#FindProdcutDetail").click(function () {

        $.ajax({

                 type: "Get",

                 url: "/api/Default/ProductDetails",

                 data: {"ProductCode": "JX00034 "}

             })

         })

    })


public class DefaultController : ApiController

{

    4 //[HttpGet]

    public string ProductDetails(string ProductCode)

    {

        return "values";

    }

}


Result




7、关于实体作为参数传递的拓展


7.1 借助[FromUri]特性传递实体


$(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  系列化与反系列化传递实体


$(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




Google Chrome 查看




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


来源:cnblogs.com/wangjiming/p/8378108.html


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值