Confused with FromBody в ядре ASP.NET
У меня есть следующий метод WEB API и есть шаблон SPA с угловым:
[HttpPost]
public IActionResult Post([FromBody]MyViewModel model)
Я думал, что на основе этой темы нет необходимости использовать [FromBody]
здесь, так как я хочу прочитать значение из тела сообщения, поэтому нет необходимости переопределять поведение по умолчанию, но если я не использую [FromBody]
, модель, которая поступает из Angular, равна нулю. Я действительно смущен, почему я должен использовать [FromBody]
, так как я использовал поведение по умолчанию?
Ответы
Ответ 1
Вопрос, на который вы ссылаетесь, ссылается на web-api. Вы используете core-mvc, который был переписан для объединения конвейеров для предыдущих версий mvc и web-api в один класс Controller
.
При публикации json
(как указано в x-www-form-urlencoded
) атрибут [FromBody]
требуется, чтобы инструктировать ModelBinder
использовать заголовок типа контента, чтобы определить, IInputFormatter
используется для чтения запроса.
Подробное объяснение привязки модели к json в core-mvc см. В статье привязки модели JSON POST в ASP.NET Core.
Ответ 2
А здесь альтернативный подход, предполагающий, что вам нужно поддерживать [FromForm]
и [FromBody]
в вашем Controller API…
Front-End (угловой код):
forgotPassword(forgotPassword: ForgotPassword): Observable<number> {
const params = new URLSearchParams();
Object.keys(forgotPassword).forEach(key => params.append(key, forgotPassword[key]));
return this.httpClient.post('${this.apiAuthUrl}/account/forgotpassword', params.toString(), { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } });
}
Back-End (код С#):
[AllowAnonymous]
[HttpPost("[action]")]
public async Task<IActionResult> ForgotPassword(ForgotPasswordViewModel model) { }
Теперь ваша подпись может остаться прежней, чтобы она могла поддерживать оба.
И еще один более постоянный подход, о котором я подумал, обращаясь.
https://benfoster.io/blog/aspnet-core-customising-model-binding-conventions.
Надеюсь, это поможет кому-то!
Ответ 3
Для тех, кто видит эту проблему .net core 3 - вам нужно добавить [ApiController] в контроллер, где вы расширяете ControllerBase.
[FromBody] необходим, только если вы работаете с контроллером MVC.
Это приводит к тому, что тело автоматически обрабатывается так, как вы ожидаете.
Документация Microsoft для атрибута ApiController