Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accepting byte[] in a .net core webapi controller

How do you accept a byte[] in WebAPI controller in .net core. Something like below:

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

I get 415 Unsupported Media Type error when testing from fiddler. Is this even possible in .net core webapi? I have searched for a while and there are no solutions for .net core. There are examples of BinaryMediaTypeFormatter which would not work with .net core webapi. If this is not possible with webapi then what is the best solution to accept a byte array in .net core web applications?

Our old application is an asp.net forms app. It will call Request.BinaryRead() to get the byte array and process the data. We are in the process of migrating this application to .net core.

Thank you.

like image 234
vjgn Avatar asked Dec 13 '22 16:12

vjgn


1 Answers

In ended up creating an InputFormatter to read posted data as byte[] array.

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

Configured this in Startup class

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

My WebAPI controller has the following method to receive the HTTP posted data (Note, my default route has Post as the action instead of Index.)

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

After doing an HTTP Post to the controller, the rawData parameter has the posted data in a byte array.

like image 196
vjgn Avatar answered Dec 31 '22 18:12

vjgn