前陣子同事在寫 WebAPI的時候,發現 Controller內的函數無法傳入超過一個以上的參數
只要傳超過一個以上,就會在Runtime當下直接噴錯,錯誤訊息為:
has more than one parameter that was specified or inferred as bound from request body. Only one parameter per action may be bound from body.
主要的意思是request body 傳入超過一個以上的參數,但在action中只應該有一個參數。
面對這樣的問題,一開始聽同事描述還覺得挺不可思議的,畢竟寫API那麼久了,從來沒聽過在Controller底下寫Method 參數最多只能給予一個。
後來請他額外測試,若是傳入基本資料型別(int,float等等) 是可以傳入多個的。
也就是說,只有傳入衍生資料型別(複雜類型),是不能過的。
但縱使是這樣,這類的錯誤訊息我依然沒遇到過。
上網研究了一下才發現,由於 Controller 內寫的Method 會默認為Action
也就是說不需要特別指定他是 [HttpGet] 或是 [HttpPost] ,他也能自動根據函數名稱來判斷,並幫你呼叫。
但這樣就會遇到一個問題,它把所有Controller裡面的Method都當成Action來呼叫了,而同時request body又只能接受一個複雜類型的參數。
因此才會噴這個錯誤。
那,為甚麼這問題我卻從來沒遇過呢?
因為筆者習慣將Controller內部的函數,都設定為private(因為都是自用)。
所以當函數設定為private就不會把它當成Action來呼叫使用,也因此這問題我從來沒發生過。
而同事遇到的這個問題,正是因為他把Controller內部的函數,統一宣告為public,因此被當作Action來呼叫,才會有這個問題。
那,如果真的想要使用public來進行呼叫呢?
就必須要在函數上加上 [NonAction] 的標籤,讓編譯器知道這個函數並不是一個Action。
因此只需要加上就可以避免此問題。
也可以使用停用推斷規則來解決此問題:
但筆者還是建議,若是複雜的商業邏輯,需要額外抽成函數來撰寫的話,應該要額外建立類別來處理業務邏輯(也就是BAL)
如果只是圖方便想直接讓Controller呼叫使用的話,也建議改成private做使用,除非萬不得已,不然建議不要設定成public,並使用 [NonAction]來宣告。
參考文章: 微軟官網-FromBody 推斷備註
以上文章敘述如有錯誤及觀念不正確,請不吝嗇指教:)
有任何家教、案子 或技術相關問題 請都歡迎聯繫我