0

I'm trying to return a firmware file, base on the existing version info that is passed to my HttpGet api via custom headers.

In my ota httpGet I have the following code:

    [HttpGet]
    public HttpResponseMessage OTA()
    {
        var result = new HttpResponseMessage();

        String returnfilename = "c:\\firmware\\device.v0.1h0.2.bin";

        byte[] dataBytes = System.IO.File.ReadAllBytes(returnfilename);

        result = new HttpResponseMessage(System.Net.HttpStatusCode.OK)
        {
            Content = new ByteArrayContent(dataBytes)
        };
        result.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
        result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
        {
            FileName = "firmware.bin"
        };
        result.Content.Headers.ContentLength = dataBytes.Length;
        result.Content.Headers.ContentMD5 = MD5.Create().ComputeHash(dataBytes);

        return result;
    }

if I call this from Postman I get the following in the Body of the response:

{"version":"1.1","content":{"headers":[{"key":"Content-Length","value":["362688"]},{"key":"Content-Type","value":["application/octet-stream"]},{"key":"Content-Disposition","value":["attachment; filename=firmware.bin"]},{"key":"Content-MD5","value":["QXp/yKD7h6jJzDpG5JyEjw=="]}]},"statusCode":200,"reasonPhrase":"OK","headers":[],"trailingHeaders":[],"requestMessage":null,"isSuccessStatusCode":true}

The actual "Headers" tab in Postman has only 4 headers listed (Which I assume are the actual headers and also explains why my device keeps reporting that the server did not send a Content-Length header):

  • Content-Type: application/json; character=utf-8
  • Date: Wed, 05 Oct 2022 15:11:59 GMT
  • Server: Kestrel
  • Transfer-Encoding: chunked

I'm obviously expecting the json above to be coming back as response headers and also the actual bin file to be sent (which it's not).

What am I doing wrong?

Gineer
  • 2,358
  • 4
  • 26
  • 40
  • Does this answer your question? [Correct way to return HttpResponseMessage as IActionResult in .Net Core 2.2](https://stackoverflow.com/questions/54136488/correct-way-to-return-httpresponsemessage-as-iactionresult-in-net-core-2-2) – JHBonarius Oct 06 '22 at 07:36
  • ASP.net Core doesn't support `HttpResponseMessage`. It uses other methods to achieve the same. If you really want to use `HttpResponseMessage`, use the helper in the best anwer from the dupe I tagged. – JHBonarius Oct 06 '22 at 07:38
  • 1
    Also read [this](https://stackoverflow.com/a/41992380). And [this answer](https://stackoverflow.com/a/42460443) shows the proper way to return a file from an asp.net core action. (I can't change the dupe, but this is a better one) – JHBonarius Oct 06 '22 at 07:41
  • @JHBonarius Yea, it looks like I will have to use Task. I'm not married to HttpResponseMessage, but now have to figure out how to respond with Http 304 Not Modified and Http 403 Forbidden, but I'll get there. Now my device is throwing an exception though. – Gineer Oct 06 '22 at 08:07

1 Answers1

0

So, the answer is that I should have used IActionResult instead of the HttpResponseMessage. Here is the code that works:

    [HttpGet]
    public async Task<IActionResult> OTA()
    {
        String returnfilename = "c:\\firmware\\device.v0.1h0.2.bin";
        if (returnfilename == String.Empty)
        {
            return StatusCode((int)HttpStatusCode.NotModified);
        }

        var stream = System.IO.File.OpenRead(returnfilename);
        return new FileStreamResult(stream, "application/octet-stream");
    }

This method automatically set's all the required headers like Content-Length etc. and the file is actually sent.

Gineer
  • 2,358
  • 4
  • 26
  • 40
  • 1
    That if statement is always false. nice of you to share your solution, but it's also described in the dupe – JHBonarius Oct 06 '22 at 16:26
  • @JHBonarius Yea that statement will always be false in this code. In the original full code there is more. I left it in here to show how you can update the HttpStatusCodes here (Which was not shown in the dup). – Gineer Oct 09 '22 at 10:50