Обычная маршрутизация не десериализует json запросов тела (ASP. NET Core API) - PullRequest
0 голосов
/ 18 февраля 2020

Проблема

Использование ApiControllerAttribute и RouteAttribute на контроллерах и действиях, все работает нормально.

Когда я изменяю код для работы с Convetional Routing, свойство 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 LINK

.../api/Main/GetExternalRemoteExternal

1 Ответ

1 голос
/ 19 февраля 2020

Атрибут [ApiController] добавляет к соглашениям несколько соглашений, которые допускают некоторые произвольные поведения, включая вывод параметров источника привязки , который по умолчанию привязывает сложные параметры к телу.

Поскольку вы не можете использовать атрибут [ApiController] с маршрутизацией на основе соглашения (поскольку одно из соглашений заключается в том, чтобы предотвратить именно это), вы можете использовать явный [FromBody] с вашими параметрами, чтобы заставить их анализироваться из JSON тело:

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