在 asp 网络控制器中接受二进制数据

Accepting binary data in asp net controller

我正在努力绑定在 http 请求正文中发送的二进制数据。

我在 Asp Net Core (NetCore 2.1) 中有以下控制器:

    [HttpPost]
    [Consumes("image/png", System.Net.Mime.MediaTypeNames.Application.Pdf, System.Net.Mime.MediaTypeNames.Image.Tiff)]
    [Route("test")]
    public IActionResult Test(IFormFile file)
    {
        return Ok(file.Length);
    }

目的是接收字节流并将其绑定到名为'file'的参数。问题是 IFormFile 变量为空。事实上,通过在控制器中放置一个断点,Route 可以完美地工作,但是当我尝试访问 'file' 变量时它会引发空指针异常。

我的疑虑与它的工作方式有关。如果我访问 Request 对象,我可以毫无问题地读取数据流。但我认为这不是正确的做法。
示例:

    [HttpPost]
    [Consumes("image/png", "image/bmp", System.Net.Mime.MediaTypeNames.Application.Pdf, System.Net.Mime.MediaTypeNames.Image.Tiff)]
    [Route("test")]
    public IActionResult Test(IFormFile binary)
    {
        var x = new System.Drawing.Bitmap(Request.Body);
        x.Save(".\file.bmp");
        return Ok("Image height: " + x.Height.ToString());
    }

如何在我的控制器中绑定以二进制形式发送的数据?

以下是邮递员发送的请求示例:
postman screenshot
raw request

P.S。尽管我知道在多部分形式

中接收数据会更好,但我有义务以二进制形式接收数据

刚刚找到解决方案:https://weblog.west-wind.com/posts/2017/Sep/14/Accepting-Raw-Request-Body-Content-in-ASPNET-Core-API-Controllers?Page=2

我一直在寻找一种将原始 Request.Body 流绑定到控制器参数的方法,而且非常简单。

我刚刚创建了一个自定义格式化程序,如下所示:

public class RawRequestBodyFormatter : InputFormatter
{
  public RawRequestBodyFormatter()
  {
    SupportedMediaTypes.Add(new MediaTypeHeaderValue("image/bmp"));
  }


/// <summary>
/// Allow image/bmp and no content type to
/// be processed
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public override Boolean CanRead(InputFormatterContext context)
{
    if (context == null) throw new ArgumentNullException(nameof(context));

    var contentType = context.HttpContext.Request.ContentType;
    if (string.IsNullOrEmpty(contentType) || contentType == "image/bmp")
        return true;

    return false;
}

/// <summary>
/// Handle bmp images
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context)
{
    var request = context.HttpContext.Request;
    var contentType = context.HttpContext.Request.ContentType;

    if (string.IsNullOrEmpty(contentType) || contentType == "image/bmp")
    {
        return await InputFormatterResult.SuccessAsync(request.Body);
    }

    return await InputFormatterResult.FailureAsync();
}

然后将相应的选项添加到我的应用程序

services.AddMvc(options =>
            options.InputFormatters.Insert(0, new 
RawRequestBodyFormatter())

现在以下控制器完全正常工作!

[HttpPost]
[Consumes("image/png", "image/bmp", System.Net.Mime.MediaTypeNames.Application.Pdf, System.Net.Mime.MediaTypeNames.Image.Tiff)]
[Route("test")]
//[JwtAuthenticationAttribute]
public IActionResult Test([FromBody]Stream file)
{
     var x = new System.Drawing.Bitmap(file);
     x.Save(".\file.bmp");
     return Ok("Image height: " + x.Height.ToString());
}