我有两个API:DMZ和Public(公共使用dmz) 1. DMZ:
public FileStreamResult GetContent(int id)
{
var content = from m in db.messagestoimages
where m.Message == id
select m;
if (content == null || content.Count() == 0)
{
return null;
}
string fileName = content.First().ImageURL;
string fullPath = AppDomain.CurrentDomain.BaseDirectory + fileName;
if (File.Exists(fullPath))
{
var fileStream = new FileStream(fullPath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
var result = new FileStreamResult(fileStream, "image/jpeg");
return result;
}
return null;
}
2:公共API
[HttpGet("{id}")]
public FileStreamResult Get(string id)
{
try
{
{
using (var client = new HttpClient())
{
try
{
string host = configuration.GetSection("MySettings").GetSection("OctopusURL").Value;
client.BaseAddress = new Uri(host);
var response = client.GetAsync("api/Content/" + id);
var stream = response.Result.Content.ReadAsStreamAsync().Result;
return new FileStreamResult(stream, "image/jpeg")
{
FileDownloadName = "test.jpeg"
};
}
catch (Exception ex)
{
return null;
}
}
}
}
catch (Exception ex)
{
return null; // 500 is generic server error
}
}
我的问题是,当我从公共API获取文件时,这是错误的,我无法打开文件,Windows表示不支持格式。我得到的文件大小小于原始文件,这可能意味着文件已部分传输或出现错误。
答案 0 :(得分:2)
直接将FileStream
返回到HTTP响应可能会导致客户端下载文件不完整。
这是因为服务器和客户端之间的流不稳定。传输可能会暂停,可能会受到影响,可能会取消。但是从服务器和磁盘读取过程需要稳定的连接和稳定的速度。
您可以使用MemoryStream
复制文件并将其返回到HTTP响应流。但是MemoryStream
使用了很多内存,这可能会导致整个服务器停止工作。
BufferedStream
返回文件是一种更好的方法。快速,稳定并且产生更少的东西。
但是从.NET Core中的服务器返回本地文件的最佳方法是使用:
Controller.PhysicalFileResult PhysicalFile(string physicalPath, string contentType, bool enableRangeProcessing);
修改您的DMZ API以使用PhysicalFile
返回文件以获得最佳性能和稳定性。像这样:
public IActionResult GetContent(int id)
{
var content = from m in db.messagestoimages
where m.Message == id
select m;
if (content == null || content.Count() == 0)
{
return NotFound();
}
string fileName = content.First().ImageURL;
string fullPath = AppDomain.CurrentDomain.BaseDirectory + fileName;
if (File.Exists(fullPath))
{
return PhysicalFile(fullPath, "image/jpeg", true);
}
return NotFound();
}
对于您的公共API,我已经使用以下代码进行了测试:
using System;
using System.IO;
using System.Net.Http;
namespace Temp
{
class Program
{
static void Main(string[] args)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("https://www.google.com");
var response = client.GetAsync("/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png");
var stream = response.Result.Content.ReadAsStreamAsync().Result;
using (var mstream = new MemoryStream())
{
stream.CopyTo(mstream);
File.WriteAllBytes("a.png", mstream.ToArray());
}
}
}
}
}
可以正常工作并成功下载了文件,该文件也可以成功打开。
我想这不是公共API的问题。