常规路由不会反序列化json正文请求(ASP.NET Core API) [英] Conventional Routing doesn't deserialize json body requests (ASP.NET Core API)
问题描述
问题
在控制器和操作上使用ApiControllerAttribute和RouteAttribute,一切正常。
当我更改代码以使用对流路由时,请求中的Identity属性始终设置为null。
带有ApiControllerAttribute的代码(已加载身份
[ApiController]
[Route( api / [controller])]]
公共类主要:ControllerBase
{
[HttpPost(nameof(GetExternalRemoteExternal))]
公共异步任务< GetByIdentityResponse< RemoteExternal>> GetExternalRemoteExternal(GetByIdentityRequest< RemoteExternalIdentity>请求)
{
返回等待GetExternal< RemoteExternal,RemoteExternalIdentity>(请求);
}
}
startup.cs
app.UseEndpoints(endpoints => endpoints.MapControllers());
具有对流路由的代码(请求具有空标识)
公共类Main:ControllerBase
{
[HttpPost]
public async Task< GetByIdentityResponse< RemoteExternal>> ; GetExternalRemoteExternal(GetByIdentityRequest< RemoteExternalIdentity>请求)
{
返回等待GetExternal< RemoteExternal,RemoteExternalIdentity>(请求);
}
}
startup.cs
app.UseEndpoints(endpoints => endpoints.MapControllerRoute(
$也不能使用p $ p>
name: default,
pattern : api / {controller} / {action})))//即使使用 api / {controller} / {action} / {?id}
公用代码
公共类GetByIdentityRequest< TIDentity> :ServiceRequest
其中TIDentity:BaseIdentity
{
public TIDentity Identity {get;组; }
}
公共类RemoteExternalIdentity:BaseIdentity
{
public ind IdX {get;组; }
}
JSON
{ $ id: 1, Identity:{ $ id: 2, IdX:10000}}
API链接
... / api / Main / GetExternalRemoteExternal
解决方案
[ApiController]
属性向控制器添加了一些约定,以启用某些自以为是的行为,包括绑定源参数推断,默认情况下,它将使复杂参数与主体绑定。
由于您不能在基于约定的路由中使用
[ApiController]
属性(因为一项约定是为了防止这种情况发生),您可以一个显式的[FromBody]
,其中包含您的参数以强制从JSON正文中进行解析:public类Main:ControllerBase
{
[HttpPost]
public async Task< GetByIdentityResponse< RemoteExternal>> GetExternalRemoteExternal(
[FromBody] GetByIdentityRequest< RemoteExternalIdentity>请求)
{
return await GetExternal< RemoteExternal,RemoteExternalIdentity>(request);
}
}
Problem
Using ApiControllerAttribute and RouteAttribute on controllers and actions, everythings work fine.
When I change the code to work with Convetional Routing, the Identity property in request is always set to null.
Code with ApiControllerAttribute (Identity loaded in request)
[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());
Code with Convetional Routing (request has null Identity)
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}"
Common code
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 LINK
.../api/Main/GetExternalRemoteExternal
解决方案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.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屋!