我为此一直苦苦挣扎,我发现了一些问题,但没有一个可以满足我的需求。我将尝试发布一个更好的问题以及我尝试过的一些方法。

情况如下:
我有一个APIGateway和一个WebApp。到目前为止,Web应用程序已将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; }
}


API网关

[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();
}


如您所见,我在JSON序列化设置中包含了TypeNameHandling.All,发送了请求,并调用了APIGateway中的Create。但是参数documentCommand为NULL。

我读过这篇文章:Asp.Net Core Post FromBody Always Null

这:ASP.NET Core MVC - Model Binding : Bind an interface model using the attribute [FromBody] (BodyModelBinder)

这:Casting interfaces for deserialization in JSON.NET

尝试了各种魔术,创建了新的构造函数,并用[JSONConstructor]标记了它们,但仍然没有成功。另外,我尝试将APIGateway Cerate方法参数类型更改为ICreateDocumentCommand,然后再次得到null。我一直在网上搜索一些模型绑定技巧,但是找不到与FromBody绑定的任何东西。我还找到了包括DI在内的一些解决方案,但我正在寻找一个简单的解决方案。我希望我们能够找到一个:)

最佳答案

事实证明,通过JSON传递带有内部接口的接口或类并不是那么容易。我添加了一个自定义JSONConverter,它现在可以使用!

关于c# - ASP.NET Core FromBody模型绑定(bind):将类与Interafece字段绑定(bind),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50601129/

10-08 21:38