我有以下的WEB API方法,并且有一个使用Angular的SPA模板:
[HttpPost]
public IActionResult Post([FromBody]MyViewModel model)
我认为,根据这个话题,由于我想要从消息正文中读取值,所以在此不需要使用[FromBody]
覆盖默认行为,但是如果我不使用[FromBody]
,那么来自Angular的模型将为空。 我很困惑,既然我已经使用了默认行为,为什么还应该使用[FromBody]
呢?我有以下的WEB API方法,并且有一个使用Angular的SPA模板:
[HttpPost]
public IActionResult Post([FromBody]MyViewModel model)
我认为,根据这个话题,由于我想要从消息正文中读取值,所以在此不需要使用[FromBody]
覆盖默认行为,但是如果我不使用[FromBody]
,那么来自Angular的模型将为空。 我很困惑,既然我已经使用了默认行为,为什么还应该使用[FromBody]
呢?针对看到此问题的任何人——.net core 3版本,您需要在扩展ControllerBase的控制器中添加[ApiController]标记。如果您使用MVC控制器,只需要添加[FromBody]标记。
这将自动处理请求正文,以满足您的期望方式。
Controller
类的 Core MVC。json
(而不是x-www-form-urlencoded
)时,需要使用[FromBody]
属性来指示ModelBinder
使用内容类型标头来确定要用于读取请求的IInputFormatter
。假设您需要在控制器API中同时支持[FromForm]
和[FromBody]
,这里有一种替代方法...
前端(Angular代码):
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' } });
}
后端(C#代码):
最初的回答[AllowAnonymous]
[HttpPost("[action]")]
public async Task<IActionResult> ForgotPassword(ForgotPasswordViewModel model) { }
请查看我的讨论https://dev59.com/BVcP5IYBdhLWcg3wXIsy#75263628关于[FromBody]
。它详细解释了一切!
但总的来说...
Angular
,像所有JavaScript API一样,不会发布传统的HTML表单字段数据(在HttpRequest正文中的名称-值对)。这些JavaScript API使用XMLHttpRequest-type
POSTS,超越了传统的基于HTML浏览器的表单POST,并直接将数据发送到服务器中的特殊JSON Content-type消息中。
Angular人员没有告诉您的是,这不是HTML类型的<form>
数据POST。Angular 劫持了Web浏览器中的所有表单字段POST调用,并向服务器发送自己的数据。
现代Web API端点中有很多不支持接收Angular HttpRequests作为特殊的POST JSON格式
,除非附加了关于所接收到的建模数据类型的额外“提示”。请记住,JSON只是一个普通的文本字符串,只有通过JSON mime-type或Content-type Http头信息来标识为“特殊文本”! JSON对象只是打包成这些特殊格式化文本字符串的数据。但大多数服务器并不知道这一点。有些服务器知道。
但这就是为什么在ASP.NET Core和WebAPI Core中我们现在有两个装饰器来帮助我们:[FromBody]
和[FromForm]
这就是ASP.NET Core或WebAPI中[FromBody]
的作用。它告诉端点监听以对象形式传入的JSON数据或文本字符串,并帮助将它们转换为ASP.NET端点方法参数列表中的建模数据类型。
[FromForm]
是相反的,它是为ASP.NET MVC和更传统的HTML名称-值数据提交到服务器而设计的,不需要所有这些额外的JavaScript和JSON格式化。如果您要从纯HTML网页向服务器发布普通HTML <form>
数据,请使用它。
所以再次强调...[FromBody]
不接受HTML表单字段名-值对,例如[FromForm]
。它是为像Angular这样发送JSON数据的API设计的。
由于您正在使用Angular,因此应该用[FromBody]
设置服务器端点。
请记住,在客户端的Angular端,现在向服务器发送数据需要以下步骤:
然而,由于Angular的Observables
和HttpClientModule
调用已经为您处理了所有这些问题,所以您应该可以顺利进行!但是,如果您没有使用Angular,则上面的列表将适用于您自定义的JavaScript调用,向新端点发送JSON。
[FromBody]
。 - Niladri[FromQuery]
。 - Niladri