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

使用HttpClient/WebClient无法下载文件,Postman可正常运行求助

问题原因与解决方案

1. ETag读取为null的原因及修复

HTTP规范要求ETag值必须用双引号包裹,你的代码中直接将哈希值赋值给ETag头,未添加引号:

Response.Headers.ETag = fileDto.Hash;

HttpClient的HttpResponseMessage.ETag是强类型的EntityTagHeaderValue,会严格按规范解析无引号的ETag值,导致解析失败返回null;但原始ETag字符串仍存在于响应头集合中,因此序列化后能看到。

修复方式:给ETag值添加双引号:

Response.Headers.ETag = $"\"{fileDto.Hash}\"";

修改后HttpClient即可正确解析response.ETag属性。

2. 200状态码但内容为空的原因及修复

你返回的Stream可能已被读取过,导致Position处于流的末尾,HttpClient读取时自然获取不到内容。Postman内部会自动重置流位置,因此能正常显示内容。

修复方式:在返回FileStreamResult前,将流的位置重置到起始点:

Stream stream = await _fileService.GetStreamAsync(id, userId);
// 重置流位置到起始处
stream.Position = 0;

优化后的完整Action代码

[HttpGet("{id}")]
public async Task<IActionResult> Get(Guid id, [FromServices] IContentTypeProvider contentTypeProvider)
{
    string? hash = Request.Headers.IfNoneMatch;
    long userId = long.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier));
    FileDto fileDto = await _fileService.GetMetadataAsync(id, userId);
    if (fileDto.Hash == hash)
    {
        return StatusCode(StatusCodes.Status304NotModified);
    }

    Stream stream = await _fileService.GetStreamAsync(id, userId);
    // 重置流位置到起始点
    stream.Position = 0;
    
    string? contentType;
    if (!contentTypeProvider.TryGetContentType(fileDto.Name, out contentType))
    {
        contentType = "application/octet-stream";
    }

    Response.Headers.CacheControl = "public";
    // 给ETag添加双引号符合HTTP规范
    Response.Headers.ETag = $"\"{fileDto.Hash}\"";
    return new FileStreamResult(stream, contentType)
    {
        FileDownloadName = fileDto.Name,
    };
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 16:02:55