當我們透過HttpClient要調用API時,Model Binding是一個重要的東西。要給API的參數可以來自URL網址參數,可以以來自網址路由,可以來自表單。
如果是POST的話,資料則是可以放在Body裡面。
這篇文章整理了一些比較常見的傳輸參數的作法。
Binding from [Route]
HttpClient Request
var clientHandler = new HttpClientHandler() { UseDefaultCredentials = true };
_httpClient = new HttpClient(clientHandler);
var responseMsg = _httpClient.GetAsync("https://localhost/api/DesignAuditRise/GetDrawingData/TestUser/Type_1").Result;
var stream = responseMsg.Content.ReadAsStreamAsync().Result;
binding 個別參數
Controller:
[HttpGet("{userName}/{darType}")] //[HttpGet]換成[Route("{userName}/{darType}")]也是可以的
public async Task<IActionResult> GetDrawingData(string userName, string darType)
{...}
Binding from [Query]
HttpClient Request:
var clientHandler = new HttpClientHandler() { UseDefaultCredentials = true };
_httpClient = new HttpClient(clientHandler);
var responseMsg = _httpClient.GetAsync("https://localhost/api/DesignAuditRise/GetDrawingData/data?param_1=TestUser&¶m_2=Type_1").Result;
var stream = responseMsg.Content.ReadAsStreamAsync().Result;
binding 個別參數
Controller:
[HttpGet("data")]
public async Task<IActionResult> GetDrawingData(string param_1, string param_2)
{...}
binding 資料模型
Controller:
[HttpGet("data")]
public async Task<IActionResult> GetDrawingData([FromQuery]GetDrawingDataDto para)
{...}
- 記得要加上 [FromQuery],不然會回應 415 Unsupported Media Type。但我記得以前在.NetFramework好像不用加這個,不知道是不是.Net才改成這樣子的。
- URL的路由data,一定要跟[HttpGet("data")]一致,不然會無法binding成功。
Model:
[BindProperties]
public class GetDrawingDataDto
{
[BindProperty(Name = "param_1", SupportsGet = true)]
public string userName { get; set; }
[BindProperty(Name = "param_2", SupportsGet = true)]
public string darType { get; set; }
}
[BindProperties]. [BindProperty]
不一定要加,但沒有加的話,URL的參數名稱就要跟Model的屬性名稱一樣。
Binding from [Body]
HttpClient Request:
var clientHandler = new HttpClientHandler() { UseDefaultCredentials = true };
_httpClient = new HttpClient(clientHandler);
var content = new StringContent(JsonConvert.SerializeObject(new { name = User.Identity.Name.Split('\\')[1], type = darType }), Encoding.UTF8, "application/json");
var responseMsg = _httpClient.PostAsync("https://localhost/api/DesignAuditRise/GetDrawingData").Result;
var stream = responseMsg.Content.ReadAsStreamAsync().Result;
[FromBody]預設會把參數轉為Json格式,Content-Type要記得用application/json,Content_Type用錯的話,會回應415
Controller:
[HttpPost]
public async Task<IActionResult> GetDrawingDataa([FromBody]GetDrawingDataDto data)
{...}
Model:
public class GetDrawingDataDto
{
public string userName { get; set; }
public string darType { get; set; }
}
- [FromBody]的參數名稱一定要跟資料模型的屬性名稱一樣,不用使用
[BindProperty]設定識別名稱。
Binding from [Form]
to be continue…
總結:
- 要Binding資料模型:要記得在參數加上[FromQuery]. [FromBody]等Attribute。
- 不Binding資料模型:只要設定好[HttpGet]的識別項名稱
- [HttpPost]的資料是存放在Body之中,記得要設定正確的Content-Type(Json),[HttpGet]則不用設定Content-Type
Ref:
1.-NET 中如何選擇 WebClient,HttpClient,HttpWebRequest
2.ASP.NET Core Model Binding 死活綁不上 - 1
3.ASP.NET Core 中的資料繫結(MSDN)