答客問:ASP.NET Core Web API簡單型別無法正常取值問題背後的問題

答客問:ASP.NET Core Web API簡單型別無法正常取值問題背後的問題

教學上,我一直認為沒有爛問題。只有懂與不懂。實務問題都是好問題。

API Question

原始問題是,他想要對一個簡單型別進行取值的動作,我們快速打造出第一版原型ASP.NET Core Web API程式碼:

// http://localhost:5000/api/test/SUCCESS (HTTP 200)
// http://localhost:5000/api/test/?status=SUCCESS (HTTP 404)
[HttpGet("{status}")]
public IActionResult Get(string status)
{
    return Ok(status);
}
SampleType from Route
SampleType from QueryString

我們試出了一個好玩的現象,透過路由系統,ASP.NET Core Web API能正確取得 status 的值,但轉個彎,怎麼 QueryString 居然取不到值!

我先不說答案,你先想想。讓我們續繼玩下去。

// http://localhost:5000/api/test/SUCCESS (HTTP 204)
// http://localhost:5000/api/test/?status=SUCCESS (HTTP 404)
[HttpGet("{status}")]
public IActionResult Test([FromQuery] string status)
{
    return Ok(status);
}
SampleType FromQuery Route
SampleType FromQuery QueryString

這一次我們加上 [FromQuery] 屬性,原本成功的那條路由的路,現在直接回我 HTTP 204,這我能理解,[FromQuery] 屬性本來就是跟框架說明來源,也就是說現在的參數應該從 QueryString 來取得,但為什麼傳遞 ?status=SUCCESS 之後還是回我 HTTP 404 呢?

傑克,這一定有問題?再改一版:

// http://localhost:5000/api/test/SUCCESS (HTTP 204)
// http://localhost:5000/api/test/?status=SUCCESS (HTTP 200)
[HttpGet("{status?}")]
public IActionResult Test([FromQuery] string status)
{
    return Ok(status);
}
SampleType FromQuery Option Route
SampleType FromQuery Option QueryString

這一次我們在路由參數上加上選擇性符號(?),Magic然後終於如我們預期的發生效果了。Route 擋下,QueryString 通過。

看到這裡,你有想通了嗎?

想不通的話,我要工商廣告了!…好啦,再給一個提示:

// http://localhost:5000/api/test/SUCCESS (HTTP 404)
// http://localhost:5000/api/test/?status=SUCCESS (HTTP 200)
[HttpGet]
public IActionResult Test([FromQuery] string status)
{
    return Ok(status);
}

結果和上面一樣(圖不重覆貼了),Route 擋下,QueryString 通過。但有那麼一丁點小差異,上面的 Route 回應 HTTP 204,下面 Route 回應HTTP 404。(我一直提示了。)

加碼題

在那麼多年的 Web API 開發時間裡,有個特別的需求,印象深刻,簡單來說,簡單型別但必須從 Body 取值。

// http://localhost:5000/api/test/
// Body (HTTP 400)
// {"status":"SUCCESS"}
// Body (HTTP 200)
// "SUCESS"
[HttpPost]
public IActionResult Test([FromBody] string status)
{
    return Ok(status);
}
SampleType FromBody JSON Object
SampleType FromBody string

奇怪了,為何傳遞 JSON 物件不行?不然再改一版:

// http://localhost:5000/api/test/
// Body (HTTP 404)
// {"status":"SUCCESS"}
// Body (HTTP 404)
// "SUCESS"
[HttpPost("{status}")]
public IActionResult Test([FromBody] string status)
{
    return Ok(status);
}
SampleType FromBody Route JSON Object
SampleType FromBody Route string

各位先生、女士兩個A士兩個 HTTP 404。

現在你覺得,簡單型別簡單嗎?


程式碼、運行結果、截圖都給各位了。如果你看完還是不懂為什麼,那麼就可以讓我們看下去。


【工商時間】

【精準解析 ASP.NET Core Web API】是我準備已久的一門課,會在這裡跟大家工商的其中一個原因是,我接受了一些任務,所以今年這一梯次過後,我會閉關一些日子(少說一年,社群在時間許可下,還是會出來分享心得),也就是說,這是往後一年最後一梯了,此梯次不報,不用再問什麼時候開 ASP.NET Core Web API 的課了,因為我也不知道。

報名活動 👉 https://skilltr.ee/RM8K5 👈 內有👀彩蛋👀,破百個 ASP.NET Core Web API 展示範例,直接大放送給各位。

沒有留言:

張貼留言

感謝您的留言,如果我的文章你喜歡或對你有幫助,按個「讚」或「分享」它,我會很高興的。