Связывание модели ASP.NET Core FromBody: связывание класса с полем Interafece - PullRequest
0 голосов
/ 30 мая 2018

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

Вот ситуация: у меня есть 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, но я ищу простое решение.Я надеюсь, что мы сможем найти один:)

1 Ответ

0 голосов
/ 31 мая 2018

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...