基于.NetFramework4.0WebAPI开发(2):ASP.NETWebAPIs
参。。。
概述:
  ASP.NET Web API 的好⽤使⽤过的都知道,没有复杂的配置⽂件,⼀个简单的ApiController加上需要的Action就能⼯作。调⽤API过程中参数的传递是必须的,本节就来谈谈API使⽤过程中参数的传递⽅式。
各种参数传递⽅式的实现:
ASP.NET Web API参数有两种传递⽅式,⼀种是请求时携带QueryString,Action中没有表中标注FromUri和FromBody属性且没有默认值的参数,Request请求时必需⼀QueryString的⽅式携带参数?A=&B=&C=1,及时没有值,也得传递,否则报404错误。
  API 开发中的FromUriAttribute属性,主要是⽤来在GET请求中传递复杂对象,并且每个API可以含有多个此类型的参数,但每个复杂对象中的属性名不能相同,否则⽆法正确传值,除⾮两个参数的相同属性的属性值相同,不过此种⽅式传递有⼀定的局限性,就是url长度限制,变相的限定此种⽅式的参数数据量的⼤⼩。
另外⼀种传递⽅式就是请求Request的发送内容携带数据,对应API开发中的FromBodyAttribute属性,此种⽅式主要应对POST请求参数的传递,可以传递复杂的类型,包括数组,list等,但是每个API有且仅有⼀个这样的参数,如果有多个,就会报⽆法将多个参数绑定到请求的内容
不多上,下⾯上代码,⼀种⼀种讲解:
1. 简单类型传递
  简单类型包括 int(decimal,long,float)、string(char)、bool、datetime、guid,主要就这⼏种
模板: public  TResult nameOfFunction([FromUrl]int i, [FromUrl]string s, ……)
=> public  TResult nameOfFunction(int i, string s, ……)
但模板: public  TResult nameOfFunction([FromUrl]ClassA a, [FromUrl]Class b, ……)
≠> public  TResult nameOfFunction(ClassA a, ClassB b, ……)
1        [HttpGet]
2public ResultData TestParameter(int i, string s, bool b, DateTime t, Guid g)
3        {
4try
5            {
6var data = new { i = i, s = s, b = b, t = t, g = g};
7return new ResultData(data);
8            }
9catch (Exception ex)
10            {
11throw ex;
12//return new ResultData(ResultType.SystemException, ex.Message);
13            }
14        }
15
16//TestParameter
17 function TestParameter() {
18var v = { i: 1, b: false, t: "2016-07-06", g: "E816F0B7-2FB7-47D9-84ED-119F58C9BEC5", s: "test"};
19    $.ajax({
20        type: "get",
21        url: host + "/mobileapi/test/TestParameter",
22        dataType: "text",
23        data: v,
24        success: function (data) {
25            alert(data);
26        },
27        error: function (x, y, z) {
28            alert("报错⽆语");
29        }
30    });
31 }
结果如下:
注意:
1. GET 类型请求的API不能含有[FromBody]属性的参数,虽然不会报错,但永远没为null,如果GET请求需要传递复杂参数,可以⽤FromUri 属性修饰参数
2. API参数没有默认值的情况下,请求的参数名称必需与API参数名称保持⼀致,但不区分⼤⼩写,且能对应上的参数个数⼀定相等,否则会报404错误。
详细列举如下:
a. 参数个数相等,但对应的参数少个 g,所有不到对应API,报404错误
1 function TestParameter() {
2var v = { i: 1, b: false, t: "2016-07-06", s: "test", a: "会报404错误" };
3    $.ajax({
4        type: "get",
5        url: host + "/mobileapi/test/TestParameter",
6        dataType: "text",
7        data: v,
8        success: function (data) {
9            alert(data);
10        },
11        error: function (x, y, z) {
12            alert("报错⽆语");
13        }
14    });
15 }
b. 参数个数不相等,但是能对应上的参数个数相等,不会报404错误
1//TestParameter
2 function TestParameter() {
3var v = { i: 1, b: false, t: "2016-07-06", s: "test", g: "E816F0B7-2FB7-47D9-84ED-119F58C9BEC5", a: "不会报404错误" };
4    $.ajax({
5        type: "get",
6        url: host + "/mobileapi/test/TestParameter",
7        dataType: "text",
8        data: v,
9        success: function (data) {
10            alert(data);
11        },
12        error: function (x, y, z) {
13            alert("报错⽆语");
14        }
15    });
16 }
如何调整使上述⼏种⽅式也能到正确的API的呢?这就需要.NET Framework的默认参数功能,API的调整如下:
1  [HttpGet]
2public ResultData TestParameter(int i, string s, bool b, DateTime t, Guid? g = null)
3        {
4try
6var data = new { i = i, s = s, b = b, t = t, g = g };
7return new ResultData(data);
8            }
9catch (Exception ex)
10            {
11throw ex;
12//return new ResultData(ResultType.SystemException, ex.Message);
13            }
14        }
以上代码最后⼀个参数g有个默认值null,这样get请求的时候可以没有g参数也能请求通过,不会报404错误。另外,值类型的参数最好定义为nullable形式(简写可以?标注),这样的参数赋值不正确的时候也不会报异常错误,只是参数值为null。特别是⽇期类,如果不是nullable类型,不传值和传错值都会报异常
上⾯例⼦中的t参数如果为  TestParameter?i=1&b=false&t=2016-37-06&s=test&g=E816F0B7-2FB7-47D9-84ED-119F58C9BEC5或者 192.168.1.135:1507/mobileapi/test/TestParameter?i=1&b=false&t=&s=test&g=E816F0B7-2FB7-47D9-84ED-119F58C9BEC5,都会报错,如果定义为nullable类型就⼀切正常:  public ResultData TestParameter(int i, string s, bool b, DateTime? t, Guid? g = null)。
2. 复杂类型传递
GET请求中复杂类型的传递需要FormUriAttribute属性配合,并且每个API可以有多个FromUri标⽰的参数,也可以在post请求中使⽤此属性标注的参数。
1  [HttpGet]
2        public ResultData TestParameter2([FromUri]List<int> ids, [FromUri]User a)
3        {
4            try
5            {
6                var data = new { ids=ids, name=a.name };
7                return new ResultData(data);
8            }
9            catch (Exception ex)
10            {
11                throw ex;
12                //return new ResultData(ResultType.SystemException, ex.Message);
13            }
14        }
测试代码:
1 function TestParameter2() {
2    var v = { ids: [1, 2, 3], name='test', age=4, weight=100 };
3    $.ajax({
4        type: "get",
5        url: host + "/mobileapi/test/TestParameter2",
6        dataType: "text",
7        data: { "": v },
8        beforeSend: function (request) {
9            request.setRequestHeader("token", $("#token").val());
10        },
11        success: function (data) {
12            alert(data);
13        },
14        error: function (x, y, z) {
15            alert("报错⽆语");
16        }
17    });
18 }
测试结果:GET请求中可以利⽤FromUri属性传递复杂类型
POST请求中复杂类型的传递需要FormBodyAttribute属性配合,并且每个API有且仅有⼀个FromBody标⽰的参数,并且只能在post请求中使⽤。
1  [HttpPost]
2public ResultData TestParameter2([FromBody]List<int> ids, [FromBody]List<int> ids2)
3        {
4try
5            {
6var data = new { ids=ids, ids2=ids2 };
7return new ResultData(data);
8            }
9catch (Exception ex)
10            {
11throw ex;
12//return new ResultData(ResultType.SystemException, ex.Message);
13            }
1        [HttpPost]
2public ResultData TestParameter2([FromBody]List<int> ids, [FromBody]ProductData pd)
3        {
4try
5            {
6var data = new { ids = ids, pd = pd };
7return new ResultData(data);
8            }
9catch (Exception ex)
10            {
11throw ex;
12//return new ResultData(ResultType.SystemException, ex.Message);
13            }
14        }
以上两个⽰例中代码编译不报错,可以正常编译,但是请求会报错,报错信息如下:测试代码:
1 function TestParameter2() {
2var v = { ids: [1, 2, 3], ids2: [4, 5, 6] };
3    $.ajax({
4        type: "post",
5        url: host + "/mobileapi/test/TestParameter2",
6        dataType: "text",
7        data: { "": v },
8        beforeSend: function (request) {
9            request.setRequestHeader("token", $("#token").val());
10        },
11        success: function (data) {
12            alert(data);
13        },
14        error: function (x, y, z) {
15            alert("报错⽆语");
16        }
17    });
18 }
1 function TestParameter2() {
2var v = { "ids": [1, 2, 3], pd: { barcode: "ddddd" } };
3    $.ajax({
4        type: "post",
5        url: host + "/mobileapi/test/TestParameter2",
6        dataType: "text",
7        data: { "": v },
8        beforeSend: function (request) {
9            request.setRequestHeader("token", $("#token").val());
10        },
11        success: function (data) {
12            alert(data);
13        },
14        error: function (x, y, z) {
15            alert("报错⽆语");
16        }
ajax实例 文件浏览
17    });
18 }
测试结果:
以上两组测试都会报⽆法将多个参数绑定到请求的内容异常
3. 数组参数的正确传递
调整⼀下API,只接收⼀个FromBody参数,并为List<int>
1        [HttpPost]
2public ResultData TestParameter2([FromBody]List<int> ids)
3        {
4try
5            {
6var data = new { ids = ids, pd = pd };
7return new ResultData(data);
8            }
9catch (Exception ex)
10            {
11throw ex;
12//return new ResultData(ResultType.SystemException, ex.Message);
13            }
14        }
测试⼀:
1//TestParameter
2 function TestParameter2() {
3var v = { "ids": [1, 2, 3] };
4    $.ajax({
5        type: "post",
6        url: host + "/mobileapi/test/TestParameter2",
7        dataType: "text",
8        data: { "": v },
9        beforeSend: function (request) {
10            request.setRequestHeader("token", $("#token").val());
11        },
12        success: function (data) {
13            alert(data);
14        },
15        error: function (x, y, z) {
16            alert("报错⽆语");
17        }
18    });
19 }
测试⼀的结果: