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?
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 .
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.
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!