Привязка модели FromBody ASP.NET Core: привязка класса к полю взаимодействия

Я много боролся с этим, я нашел несколько вопросов, но ни один не смог ответить на мои потребности. Я постараюсь опубликовать лучший вопрос и некоторые вещи, которые я пробовал.

Вот такая ситуация: У меня есть APIGateway и WebApp. WebApp отправляет запросы POST на APIGateway, пока все хорошо. Я использую атрибут FromBody для отправки более крупных объектов, и это тоже было хорошо, пока я не представил интерфейсы :))

Вот код:

Веб-приложение:

public interface ICommand
{
    Guid CorrelationId { get; set; }

    Guid SocketId { get; set; }
}

public class Command : ICommand
{       
    public Command(Guid CorrelationId, Guid SocketId)
    {
        this.CorrelationId = CorrelationId;
        this.SocketId = SocketId;
    }

    public Guid CorrelationId { get; set; } = new Guid();

    public Guid SocketId { get; set; } = new Guid();
}    

public interface IDocument
{
    Guid Id { get; set; }

    ulong Number { get; set; }
}

public class Document : IDocument
{
    public Guid Id { get; set; } = new Guid();

    public ulong Number { get; set; } = 0;
}

public interface ICreateDocumentCommand : ICommand
{
    IDocument Document { get; set; }
}

public class  CreateDocumentCommand : Command, ICreateDocumentCommand
{
    public CreateDocumentCommand(IDocument Document, ICommand Command) : base(Command.CorrelationId, Command.SocketId)
    {
        this.Document = Document;
    }

    public IDocument Document { get; set; }
}

APIGateway:

[HttpPost]
public async Task<IActionResult> Create([FromBody]CreateDocumentCommand documentCommand)
{
    if (documentCommand == null)
    {
       return StatusCode(403);
    }
    return Json(documentCommand.Document.Id);
}

Пример использования:

public class InventoryList : Document
{
    public Guid WarehouseId { get; set; } = new Guid();
}

// Example document class
////////////////////////////////////////
// Example POST Request

ICommand command = new Command(messageId, socketId);
switch (item.GetType().Name)
{
    case "InventoryList":
    command = new CreateDocumentCommand((InventoryList)item, command);
    break;
}
string result = await PostAsync($"{apiGatewayAddress}{item.GetType().BaseType.Name}/Create", command, accessToken);

Моя функция отправки POST:

public async Task<string> PostAsync<T>(string uri, T item, string authorizationToken = null, string authorizationMethod = "Bearer")
{
    JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All };

    HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Post, uri);
    requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 

    requestMessage.Content = new StringContent(JsonConvert.SerializeObject(item, typeof(T), jsonSerializerSettings), System.Text.Encoding.UTF8, "application/json");
    return await _client.SendAsync(requestMessage).Result.Content.ReadAsStringAsync();
}

Как видите, я включил TypeNameHandling.All в настройки сериализации JSON, запрос отправляется и вызывается Create в APIGateway. Однако параметр documentCommand имеет значение NULL.

Я читал это:Asp.Net Core Post FromBody всегда равен нулю

Этот:ASP.NET Core MVC - Привязка модели: привязка модели интерфейса с помощью атрибута [FromBody] (BodyModelBinder)

Этот:Приведение интерфейсов для десериализации в JSON.NET

Пробовал всевозможные фокусы, создал новые конструкторы, пометил их [JSONConstructor], но безуспешно. Также я попытался изменить тип параметра метода APIGateway Cerate на ICreateDocumentCommand и снова получил ноль. Я искал некоторые уловки привязки моделей в Интернете, но не смог найти ничего для привязки с FromBody. Я также нашел какое-то решение, включая DI, но я ищу простое решение. Надеюсь, нам удастся его найти :)

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
0
1 233
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Оказывается, передать интерфейсы или классы с интерфейсами внутри как JSON не так просто. Я добавил собственный JSONConverter, и теперь он работает!

Было бы здорово, если бы вы поделились своим пользовательским JsonConverter в своем ответе.

Doug Wilson 22.10.2018 17:55

@DougWilson Что-то пошло не так, и тогда я создал отдельные контроллеры и типы для разных типов документов. Как CreateDocumentCommand -> CreateInvoiceCommand, CreateSomeOtherDocumentCommand. И внутри этих классов есть документ соответствующего типа. Это было то, от чего я пытался убежать ... Во всяком случае, это работает.

Kaloyan Manev 24.10.2018 18:49

Другие вопросы по теме