在測試ASP.NET Core API 項目的時候,發現背景接口參數為類型對象,對于PostMan和Ajax的Post方法傳Json資料都擷取不到相應的值,後來在類型參數前面加了一個[FromBody]屬性才擷取到。但是我看微軟官方文檔示範代碼中并沒有添加[FromBody],難道是微軟官方文檔寫錯了,按道理應該不會。Google裡看到一片篇文章裡的一個細節,又追回微軟官方文檔發現可行,于是記下去掉這個煩人的[FromBody]過程
修改之前測試
背景通過Visual Studio生成ASP.NET Core API項目之後,在Controller裡添加如下代碼
// POST: api/Todo
[HttpPost]
public async Task<ActionResult<TodoItem>> PostTodoItem(TodoItem todoItem)
{
_context.TodoItems.Add(todoItem);
await _context.SaveChangesAsync();
return CreatedAtAction("GetTodoItem", new { id = todoItem.Id }, todoItem);
}
postMan調用
如圖所示,name的值為walk dog,背景api擷取結果如第三張圖所示:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5yN4cTN1gjMzITMtEDNxcDNwETOxkTMxATOxAjMtYzN3ATM38CXxATOxAjMvwlN3cDMxczLcd2bsJ2Lc12bj5ycn9Gbi52YugTMwIzZtl2Lc9CX6MHc0RHaiojIsJye.png)
Jquery調用
如圖所示,前端會将頁面填寫的值進行序列化,但是後端依然擷取不到值:
傳回結果
不論是postMan調用還是ajax調用,背景都擷取不到name值和isComplete的值
增加[FromBody]
測試如下:發現可以擷取到相應的值,但是如果每個Post方法并含有類型參數的請求前面都添加這麼一個屬性,相比以前的Asp.Net Api 操作有點不習慣,甚至多餘
進行修改
增加一個Contrller,命名為BaseController, 并繼承Controller ,代碼如下所示:
public class BaseController: Controller
{
}
然後在BaseController類上增加屬性[ApiController],最終如下圖所示:
最後修改所有API控制器的父類,改為繼承BaseController
修改之後測試
如圖所示,此時可以看到已經沒有[FromBody]了,需要注意一點是請求的ContentType必須為:application/json
總結
如果沒有該[ApiController]屬性,則需要顯式定義綁定源屬性。如果沒有[ApiController]或其他綁定源屬性[FromQuery],ASP.NET Core運作時會嘗試使用複雜的對象模型綁定器。複雜對象模型綁定器從值提供程式(具有已定義的順序)中提取資料。例如,'body model binder'總是選擇加入。