首頁 > 軟體

ASP.NET中Web API的引數繫結

2022-03-08 13:00:10

在這篇文章中,我們將學習WebAPI如何將HTTP請求資料繫結到一個操作方法的引數中。

操作方法在WebAPI控制器中可以有一個或多個不同型別的引數。它可以是基本資料型別或複雜型別。WebAPI根據URL的查詢字串或請求主體中引數型別來繫結操作方法的引數。

如果引數型別是基本資料型別(int,double,string,DateTime,bool等),WebAPI預設將會從URL中獲取引數值(即通過querystring)獲取。

如果引數型別的複雜型別,WebAPI預設從請求主體中獲取引數值。

下表列出了Web API引數繫結的預設規則。

HTTP方法Query StringRequest Body
GET簡單型別不能從請求主體中獲取引數值
POST簡單型別複雜型別
PUT簡單型別複雜型別
PATCH簡單型別複雜型別
DELETE簡單型別不能從請求主體中獲取引數值

我們先來看看建立帶MVC的Web API專案時自動生成的Values控制器是如何定義的。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace WebAPIContainMVC.Controllers
{
    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)可以將四種方法的引數傳遞迴為兩大類,而這兩大類又集中在Get和Post中體現(Put是Get和Post的組合,Delete和Get型別),所以說研究WebAPI的引數繫結,只需要研究Get和Post方法的引數傳遞即可,Get對應Request-url,Post對應Request-Body。

在本篇文章中,使用者端呼叫使用Fiddler工具進行測試。

一、Get

1、基本資料型別作為方法引數

1.1方法只含有一個引數(形參可以傳遞進來)

方法定義如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using WebAPIContainMVC.Entity;

namespace WebAPIContainMVC.Controllers
{
    public class StudentController : ApiController
    {
        [HttpGet]
        public string GetStudentById(int id)
        {
            string strResult=string.Empty;
            List<Student> list = new List<Student>();
            Student stu = new Student()
            {
              StudentId=1,
              Name="Tom",
              Age=20,
              Sex="男"
            };
            list.Add(stu);
            list.ForEach(p =>
            {
                if (p.StudentId.Equals(id))
                {
                    strResult = "存在該學生資訊";
                }
                else
                {
                    strResult = "對不起,找不到該學生資訊";
                }
            });

        return strResult;
        }
    }
}

使用者端呼叫

結果:

雙擊左側的程序,得到如下的結果

1.2、方法含有多個引數(形參可以傳遞進來)

方法定義如下:

public string GetStudentByIdAndName(int id,string name)
{
            string strResult = string.Empty;
            List<Student> list = new List<Student>();
            Student stu = new Student()
            {
                StudentId = 1,
                Name = "Tom",
                Age = 20,
                Sex = "男"
            };
            list.Add(stu);
            list.ForEach(p =>
            {
                if (p.StudentId.Equals(id)&&p.Name.Equals(name))
                {
                    strResult = "存在該學生資訊";
                }
                else
                {
                    strResult = "對不起,找不到該學生資訊";
                }
            });
 
            return strResult;
}

URL地址:http://localhost:63512/api/student?id=1&&name=Tom

結果如下:

2、實體物件型別作為方法引數(形參不能傳遞進來)

方法定義如下:

[HttpGet]
public string GetStudent(Student student)
{
            string strResult = string.Empty;
            List<Student> list = new List<Student>();
            Student stu = new Student()
            {
                StudentId = 1,
                Name = "Tom",
                Age = 20,
                Sex = "男"
            };
            list.Add(stu);
            if (student != null)
            {
                list.ForEach(p =>
                {
                    if (p.StudentId.Equals(student.StudentId))
                    {
                        strResult = "存在該學生資訊";
                    }
                    else
                    {
                        strResult = "對不起,找不到該學生資訊";
                    }
                });
            }
            else
            {
                strResult = "引數值為Null";
            }
      
 
            return strResult;
}

使用者端呼叫結果如下:

3、基本資料型別和實體物件混合作為方法引數(基本資料型別可以傳遞進來,實體物件不能傳遞進來)

4、總結

(1)查詢字串引數名稱和操作方法引數名稱必須相同(不區分大小寫)。引數的先後順序可以不一致。

(2)Get()引數傳遞的本質是URL字串拼接,但是URL字串的長度受限制。

(3)Get()的引數支援基本資料型別,不支援實體資料型別。

(4)Get()引數的傳遞是在Http請求的頭部傳遞,而不支援Request-Body傳遞。

(5)Get型別的方法命名,儘量採用“Get+方法名”的命名方式,在方法前面加上特性:[HttpGet]。

二、Post

1、Post引數傳遞是在Request-Body內傳遞。

2、Post引數可以傳遞基本資料型別,也可以傳遞實體資料型別。

3、Post操作方法只能包含一個實體資料型別,因為只能允許一個引數讀取Request-Body中的資料。

4、Post傳遞引數時,無論是基本型別引數還是實體型別,均需要藉助[FromBody]特性。(有些情況下不寫[FromBody]特性也可以把引數傳遞進來,但為了規範化,最好是加上該特性)。

5、Post型別的方法命名,儘量採用“Post+方法名”的命名方式,在方法前面加上特性:[HttpPost]。

三、FromURI與FromBody

在預設情況下,WebAPI是從查詢字串中得到基本資料型別引數的值,從請求主體中得到複雜型別引數的值,如果想改變這種預設情況怎麼辦?

可以使用[FromURI]屬性,是WebAPI從查詢字串中獲取複雜型別引數的值,使用[FromBody]屬性可以使WebAPI從請求主體中獲取基本資料型別引數的值。

例如下面的Get方法

[HttpGet]
public string GetStudentById([FromUri]Student stu)
{
         
}

Get方法中包括複雜的型別引數,引數新增了[FromUri]屬性,WebAPI將試圖從查詢字串中得到Student型別引數的值。

同樣,參考下面的Post方法:

[HttpPost]
public string Post([FromBody]string name)
{ }

WebAPI將從請求主體中獲取基本型別引數的值,而不是從請求字串中獲取。

到此這篇關於ASP.NET中Web API引數繫結的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com