You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 6.0中HttpGet返回二进制文件未返回文件及正确头问题

问题原因

在ASP.NET Core中,直接返回HttpResponseMessage类型对象时,框架会把它当作普通CLR对象做JSON序列化,而非将其作为真实HTTP响应输出。这就是为什么你看到响应体是HttpResponseMessage的JSON结构,自定义响应头、二进制固件内容都没生效,设备自然收不到Content-Length头。

解决方案

推荐用ASP.NET Core原生的结果类型实现需求,以下是几种可行方式:

方式1:用FileContentResult(最简洁)

直接返回FileContentResult,框架会自动处理响应头和二进制内容:

[HttpGet]
public IActionResult OTA()
{
    string returnfilename = @"c:\firmware\device.v0.1h0.2.bin";
    byte[] dataBytes = System.IO.File.ReadAllBytes(returnfilename);
    
    // 计算MD5并转Base64
    var md5Hash = MD5.Create().ComputeHash(dataBytes);
    string md5Base64 = Convert.ToBase64String(md5Hash);
    
    // 添加Content-MD5响应头
    Response.Headers.Add("Content-MD5", md5Base64);
    
    // 返回文件,自动设置Content-Type、Content-Disposition、Content-Length
    return File(dataBytes, "application/octet-stream", "firmware.bin");
}

方式2:用ResponseMessageResult包装HttpResponseMessage

如果坚持用HttpResponseMessage,需要用ASP.NET Core提供的适配类型包装:

using Microsoft.AspNetCore.Mvc;

[HttpGet]
public IActionResult OTA()
{
    string returnfilename = @"c:\firmware\device.v0.1h0.2.bin";
    byte[] dataBytes = System.IO.File.ReadAllBytes(returnfilename);

    var 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 new ResponseMessageResult(result);
}

注:如果项目没有相关引用,需要安装Microsoft.AspNetCore.Mvc.WebApiCompatShim包,用于兼容旧Web API特性

方式3:直接操作HttpContext.Response(底层方式)

直接写入响应流,完全控制响应内容:

[HttpGet]
public async Task OTA()
{
    string returnfilename = @"c:\firmware\device.v0.1h0.2.bin";
    byte[] dataBytes = System.IO.File.ReadAllBytes(returnfilename);
    
    var response = HttpContext.Response;
    response.ContentType = "application/octet-stream";
    response.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
    {
        FileName = "firmware.bin"
    }.ToString();
    response.Headers.ContentLength = dataBytes.Length;
    response.Headers.ContentMD5 = Convert.ToBase64String(MD5.Create().ComputeHash(dataBytes));
    
    await response.Body.WriteAsync(dataBytes);
    await response.Body.FlushAsync();
}
额外注意事项
  • 路径中的反斜杠要转义,或者用@符号避免转义问题(比如@"c:\firmware\device.v0.1h0.2.bin")
  • 确保应用程序有读取c:\firmware目录文件的权限,否则会触发文件访问异常
  • 如果固件文件体积大,别用File.ReadAllBytes一次性加载到内存,建议用FileStream流式返回,减少内存占用

内容的提问来源于stack exchange,提问作者Gineer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 11:01:05