c# – ASP.NET Core FromBody模型绑定:使用Interafece字段绑定一个类

我一直在苦苦挣扎,我发现了一些问题,但没有人能满足我的需求.我会尝试发布一个更好的问题和一些我尝试过的事情.

情况如下:
我有一个APIGateway和一个WebApp.到目前为止,WebApp向APIGateway发送了POST请求.我使用FromBody属性发送更大的对象,这也很好,直到我介绍接口:))

这是一些代码:

Web应用程序:

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

如您所见,我在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,现在可以使用了!

点赞