使用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
相关产品推荐
相关产品推荐

