前言
關於Dapper的介紹,其實多到可以算月經文了XD
不過剛好有機會使用到,所以就順著介紹一下。
前陣子同事在寫 WebAPI的時候,發現 Controller內的函數無法傳入超過一個以上的參數
只要傳超過一個以上,就會在Runtime當下直接噴錯,錯誤訊息為:
1 | 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來進行呼叫呢?因此只需要加上就可以避免此問題。
也可以使用停用推斷規則來解決此問題:
但筆者還是建議,若是複雜的商業邏輯,需要額外抽成函數來撰寫的話,應該要額外建立類別來處理業務邏輯(也就是BAL)如果只是圖方便想直接讓Controller呼叫使用的話,也建議改成private做使用,除非萬不得已,不然建議不要設定成public,並使用 [NonAction]來宣告。