常规路由不会反序列化 json 正文请求(ASP.NET Core API) [英] Conventional Routing doesn't deserialize json body requests (ASP.NET Core API)
问题描述
问题
在控制器和动作上使用 ApiControllerAttribute 和 RouteAttribute,一切正常.
Using ApiControllerAttribute and RouteAttribute on controllers and actions, everythings work fine.
当我更改代码以使用 Convetional Routing 时,请求中的 Identity 属性始终设置为 null.
When I change the code to work with Convetional Routing, the Identity property in request is always set to null.
带有 ApiControllerAttribute 的代码(请求中加载的身份)
[ApiController]
[Route("api/[controller]")]
Public Class Main : ControllerBase
{
[HttpPost(nameof(GetExternalRemoteExternal))]
public async Task<GetByIdentityResponse<RemoteExternal>> GetExternalRemoteExternal(GetByIdentityRequest<RemoteExternalIdentity> request)
{
return await GetExternal<RemoteExternal, RemoteExternalIdentity>(request);
}
}
startup.cs
app.UseEndpoints(endpoints => endpoints.MapControllers());
具有常规路由的代码(请求具有空标识)
Public Class Main : ControllerBase
{
[HttpPost]
public async Task<GetByIdentityResponse<RemoteExternal>> GetExternalRemoteExternal(GetByIdentityRequest<RemoteExternalIdentity> request)
{
return await GetExternal<RemoteExternal, RemoteExternalIdentity>(request);
}
}
startup.cs
app.UseEndpoints(endpoints => endpoints.MapControllerRoute(
name: "default",
pattern: "api/{controller}/{action}")) //Not work even with "api/{controller}/{action}/{?id}"
通用代码
public class GetByIdentityRequest<TIDentity> : ServiceRequest
where TIDentity : BaseIdentity
{
public TIDentity Identity { get; set; }
}
public class RemoteExternalIdentity : BaseIdentity
{
public int IdX { get; set; }
}
JSON
{"$id":"1","Identity":{"$id":"2","IdX":10000}}
API 链接
.../api/Main/GetExternalRemoteExternal
推荐答案
[ApiController]
属性 向控制器添加了一些约定,以实现一些自以为是的行为,包括 绑定源参数推断使复杂参数默认从正文绑定.
The [ApiController]
attribute adds a few conventions to controllers that enables some opinionated behaviors, including binding source parameter inference that will make complex parameters bind from the body by default.
由于您不能将 [ApiController]
属性与基于约定的路由一起使用(因为约定之一就是防止这种情况发生),您可以使用显式 [FromBody]
使用您的参数强制从 JSON 正文解析它们:
Since you cannot use the [ApiController]
attribute with convention-based routing (since one of the convention is to prevent exactly that), you can use an explicit [FromBody]
with your parameters to force them to be parsed from the JSON body:
public class Main : ControllerBase
{
[HttpPost]
public async Task<GetByIdentityResponse<RemoteExternal>> GetExternalRemoteExternal(
[FromBody] GetByIdentityRequest<RemoteExternalIdentity> request)
{
return await GetExternal<RemoteExternal, RemoteExternalIdentity>(request);
}
}
这篇关于常规路由不会反序列化 json 正文请求(ASP.NET Core API)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!