Я много боролся с этим, нашел несколько вопросов, но ни один не смог ответить на мои потребности.Я постараюсь опубликовать лучший вопрос и некоторые из вещей, которые я пробовал.
Вот ситуация: у меня есть APIGateway и WebApp.WebApp отправляет запросы POST на APIGateway, пока все хорошо.Я использую атрибут FromBody для отправки больших объектов, и это было нормально, пока я не представил интерфейсы:))
Вот код:
WebApp:
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 FromBody Always Null
Это: ASP.NET Core MVC - привязка модели: привязка модели интерфейса с помощью атрибута [FromBody] (BodyModelBinder)
This: Casting interfacesдля десериализации в JSON.NET
Перепробовал все виды магических трюков, создал новые конструкторы, пометил их [JSONConstructor], но все равно безуспешно.Также я попытался изменить тип параметра метода APIGateway Cerate на ICreateDocumentCommand и снова получил значение NULL.Я искал некоторые хитрости привязки модели в Интернете, но я не смог найти ничего для привязки с FromBody.Я также нашел какое-то решение, в том числе DI, но я ищу простое решение.Я надеюсь, что мы сможем найти один:)