【问题标题】:Accepting byte[] in a .net core webapi controller在 .net 核心 webapi 控制器中接受 byte[]
【发布时间】:2018-06-19 07:16:20
【问题描述】:

如何在 .net 核心的 WebAPI 控制器中接受一个字节[]。如下所示:

    [HttpPost]
    public IActionResult Post(byte[] rawData)
    {
        try
        {
            System.Diagnostics.Trace.WriteLine("Total bytes posted: " + rawData?.Length);
            return StatusCode(200);
        }
        catch(Exception ex)
        {
            return StatusCode(500, $"Error. msg: {ex.Message}");
        }
    }

从提琴手进行测试时,我收到 415 Unsupported Media Type 错误。 这在.net core webapi中甚至可能吗?我已经搜索了一段时间,没有.net核心的解决方案。有一些 BinaryMediaTypeFormatter 示例不适用于 .net 核心 webapi。如果 webapi 无法做到这一点,那么在 .net 核心 Web 应用程序中接受字节数组的最佳解决方案是什么?

我们的旧应用程序是一个 asp.net 表单应用程序。它将调用 Request.BinaryRead() 来获取字节数组并处理数据。我们正在将此应用程序迁移到 .net 核心。

谢谢。

【问题讨论】:

  • 另一种方法可能是接受一个表示字节数组的字符串并在控制器端点中处理它。
  • @DavidL 我确实探索了这个选项,但这对于我的情况来说不是一个可能的解决方案。我们不能要求客户最终更改任何内容。

标签: c# asp.net-core asp.net-core-webapi


【解决方案1】:

最终创建了一个 InputFormatter 来将发布的数据读取为 byte[] 数组。

public class BinaryInputFormatter : InputFormatter
{
    const string binaryContentType = "application/octet-stream";
    const int bufferLength = 16384;

    public BinaryInputFormatter()
    {
        SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse(binaryContentType));
    }

    public async override Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context)
    {
        using (MemoryStream ms = new MemoryStream(bufferLength))
        {
            await context.HttpContext.Request.Body.CopyToAsync(ms);
            object result = ms.ToArray();
            return await InputFormatterResult.SuccessAsync(result);
        }
    }

    protected override bool CanReadType(Type type)
    {
        if (type == typeof(byte[]))
            return true;
        else
            return false;
    }
}

在启动类中配置这个

        services.AddMvc(options =>
        {
            options.InputFormatters.Insert(0, new BinaryInputFormatter());
        });

我的 WebAPI 控制器具有以下方法来接收 HTTP 发布的数据(注意,我的默认路由将 Post 作为操作而不是索引。)

    [HttpPost]
    public IActionResult Post([FromBody] byte[] rawData)
    {
        try
        {
            System.Diagnostics.Trace.WriteLine("Total bytes posted: " + rawData?.Length);
            return StatusCode(200);
        }
        catch(Exception ex)
        {
            return StatusCode(500, $"Error. msg: {ex.Message}");
        }
    }

在对控制器进行 HTTP Post 之后,rawData 参数将发布的数据保存在一个字节数组中。

【讨论】:

  • 有趣的是,如果你这样做,然后使用 VS 2019 内置的 OpenAPI/swagger 生成器,生成的 swagger.json 将正确描述 application/octet-stream 作为可能的输入选项,但是从此 swagger.json 生成的客户端代码(同样,使用 VS 2019 内置的 Add - Service reference - OpenAPI)将完全搞砸。它会发送“Content-type: application/octent-stream”,但它会将二进制数据编码为 json/base64,因此 API 会看到垃圾。
猜你喜欢
  • 2019-07-16
  • 1970-01-01
  • 2019-01-03
  • 2020-02-18
  • 1970-01-01
  • 1970-01-01
  • 2021-07-14
  • 2023-03-20
  • 2020-06-19
相关资源
最近更新 更多