web-dev-qa-db-fra.com

Confondu avec FromBody dans ASP.NET Core

J'ai la méthode d'API WEB suivante et j'ai un modèle SPA avec Angular:

[HttpPost]
public IActionResult Post([FromBody]MyViewModel model)

J'ai pensé, sur la base de this topic, il n'est pas nécessaire d'utiliser [FromBody] ici, puisque je veux lire la valeur du corps du message, donc il n'est pas nécessaire de remplacer le comportement par défaut, mais, si je n'utilise pas [FromBody], le modèle qui vient de Angular est nul. Je suis vraiment confus, pourquoi devrais-je utiliser [FromBody], puisque j'ai utilisé le comportement par défaut?

11
J.P

La question à laquelle vous avez lié fait référence à l'API Web. Vous utilisez core-mvc qui a été réécrit pour fusionner les pipelines des versions précédentes de mvc et web-api en une seule classe Controller.

Lors de la publication de json (comme apposé sur x-www-form-urlencoded), le [FromBody] l'attribut est requis pour demander à ModelBinder d'utiliser l'en-tête de type de contenu pour déterminer le IInputFormatter à utiliser pour lire la demande.

Pour une explication détaillée de la liaison de modèle à json dans core-mvc, reportez-vous à Modèle de liaison JSON POST dans ASP.NET Core .

10
user3559349

Pour tous ceux qui voient ce problème .net core 3 - vous devez ajouter [ApiController] au contrôleur où vous étendez ControllerBase. Le [FromBody] n'est nécessaire que si vous utilisez un contrôleur MVC.

Cela provoque le traitement automatique du corps de la manière que vous attendez.

documentation Microsoft pour l'attribut ApiController

0
Rob

Et voici une autre approche en supposant que vous devez prendre en charge [FromForm] et [FromBody] dans votre API de contrôleur…

Front-End (code angulaire):

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 (code C #):

[AllowAnonymous]
[HttpPost("[action]")]
public async Task<IActionResult> ForgotPassword(ForgotPasswordViewModel model) { }

Maintenant, votre signature peut rester la même pour pouvoir prendre en charge les deux.

Et une autre approche plus permanente à laquelle j'ai pensé en abordant.

https://benfoster.io/blog/aspnet-core-customising-model-binding-conventions .

J'espère que cela aide quelqu'un!

0
Tim Harker