在WebApi開發過程中,遇到一些客戶端參數格式傳輸錯誤,經常被問到參數如何傳遞的一些問題,因此就用這篇博客做一下總結,肯定其它地方呢也有類似的一些文章,但是我還是喜歡通過這種方式將自己的理解記錄下來
在客戶端調用WebApi的一些接口時,最常使用到的HTTP方式有Get, Post, Put, Delete四個,下面會將這四個分成兩類進行說明
第一類:Get/Delete
Delete在Body中傳遞參數有爭議, 因此強烈建議只在URL中傳遞參數,所以這個分類里面只考慮通過URL傳遞參數的情況。
在URL中可以傳遞多個參數,但總長度有URL長度限制,參數之間使用&分隔,如以下格式:http://localhost:12345/api/Echo?arg1=value1&arg2=value2&arg3=中文
,其中的中文等特殊字符需要使用urlencode進行轉義,在WebApi中接收的參數可以是多個單獨的參數,也可以是由多個參數封裝的對象(這個轉換會由框架自動完成)
例如:
http://localhost:12345/api/Echo/Single?arg1=1&arg2=2
http://localhost:12345/api/Echo/Multiple?arg1=1&arg2=2&strArg1=hello&strArg2=world
[RoutePrefix("api/Echo")]
public class EchoController : ApiController
{
[Route("Single")]
public void Get2([FromUri]int arg1, [FromUri]int arg2)
{ }
[Route("Muliple")]
public void Get3([FromUri]int arg1, [FromUri]int arg2, [FromUri]Arg arg3)
{ }
}
public class Arg
{
public string strArg1 { get; set; }
public string strArg2 { get; set; }
}
第二類:Post/Put
Post和Put在參數傳遞時既可以在URL中傳遞,也可以在Body中傳遞,當然一起傳也是可以的,URL傳遞符合上面所描述的情況,下面着重說一下在Body中傳值的情況。
Body正文只接收一個參數的傳遞,但不限該參數是一個值還是一個對象,所以如果想要在Body中傳遞多個參數,需要將這多個參數封裝成一個對象
一個值參數
Api中定義的接收方式(還有多種接收參數的方式,這里只是用這一種方式進行舉例):
[Route("Single")]
public void Post1([FromBody]int arg1)
{
}
Body中的正文:
1
多個值參數
Api中定義的接收方式:
[Route("Single")]
public void Post1([FromBody]int arg1, [FromBody]int arg2)
{
}
Body中的正文(以json格式為例):
{
"arg1":1,"arg2":2
}
此種方式會導致服務器報500錯誤,因為服務器端不能正確解析所傳參數
對象參數:
Api中定義的接收方式:
[Route("SingleObject")]
public void Post2([FromBody]Arg arg)
{
}
Body中正文內容(以json為例,若要以form方式傳輸,請參考form格式):
{
"strArg1":"hello", "strArg2":"world"
}
若有多傳的值會被自動忽略掉
Body正文格式
Body正文格式中分json和form兩種傳遞方式,若使用form方式傳遞,請將http頭Content-Type
設置為application/x-www-form-urlencoded
, 其中的x-www-form-urlencoded
為正文指定編碼方式,而使用json形式傳遞, 請將http頭Content-Type
設置為application/json; charset=utf-8
,參數正文不需要使用特殊的編碼處理,不過強烈建議使用json這種傳輸方式,下面是兩個分別使用form和json傳遞的http包:
Form方式
POST /api/test HTTP/1.1
Connection: keep-alive
Content-Length: 35
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8
Host: localhost:12345
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36
arg1=1&arg2=2&content=%E6%B5%8B%E8%AF%95
Json方式
POST /api/test HTTP/1.1
Connection: keep-alive
Content-Length: 35
Content-Type: application/json; charset=UTF-8
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8
Host: localhost:12345
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36
{
"arg1":1,
"arg2":2,
"content":"測試"
}