【问题标题】:Conventional Routing doesn't deserialize json body requests (ASP.NET Core API)常规路由不会反序列化 json 正文请求(ASP.NET Core API)
【发布时间】:2020-06-02 09:16:13
【问题描述】:

问题

在控制器和动作上使用 ApiControllerAttribute 和 RouteAttribute,一切正常。

当我更改代码以使用传统路由时,请求中的 Identity 属性始终设置为 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

【问题讨论】:

  • 你能显示你的控制器的注释吗?另外,您使用什么 URL 来发出请求?
  • 尝试在参数类型GetByIdentityRequest&lt;RemoteExternalIdentity&gt; 之前放置一个[FromBody][ApiController] 属性添加了一些约定,这可能会导致此处的差异。

标签: json asp.net-core .net-core routes asp.net-apicontroller


【解决方案1】:

[ApiController] attribute 为控制器添加了一些约定,以启用一些自以为是的行为,包括默认情况下使复杂参数从主体绑定的binding source parameter inference

由于您不能将 [ApiController] 属性与基于约定的路由一起使用(因为约定之一就是为了防止这种情况发生),您可以使用带有参数的显式 [FromBody] 来强制从 JSON 中解析它们正文:

public class Main : ControllerBase
{
    [HttpPost]
    public async Task<GetByIdentityResponse<RemoteExternal>> GetExternalRemoteExternal(
        [FromBody] GetByIdentityRequest<RemoteExternalIdentity> request)
    {
        return await GetExternal<RemoteExternal, RemoteExternalIdentity>(request);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-29
    • 2017-12-03
    • 1970-01-01
    • 1970-01-01
    • 2019-09-23
    • 1970-01-01
    • 1970-01-01
    • 2018-11-09
    相关资源
    最近更新 更多