c# - 从使用 DMZ API 的公共 ASP.NET Core API 获取文件
问题描述
我有两个 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 说不支持格式。我得到的文件大小小于原始文件,这可能意味着文件被部分传输或有错误。
解决方案
直接返回FileStream
到 HTTP 响应可能会导致客户端下载文件不完整。
这是因为服务器和客户端之间的流不稳定。传输可能会暂停,可能会受到影响,可能会取消。但是从服务器和磁盘读取过程需要稳定的连接和稳定的速度。
您可以使用 aMemoryStream
复制文件并将其返回到 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 来说不是问题。
推荐阅读
- python - 你能找出这里的错误吗?
- video - 视频在 Chrome 中运行之前,我的网站中有奇怪的垂直线
- nginx - Nginx 正则表达式 pcre_compile() 失败
- assembly - 正确的寻址方式
- mobile - 将大型复杂的 3D 场景带入移动设备,请帮助我们提出您的想法![没有限制]
- swift - 将collectionView连接到tableView
- javascript - 点赞按钮怎么实现?
- javascript - Html 视频标签控件在 Firefox 中不起作用
- django - 在 django 模型中获取多对多文件以及模型字段
- rust - TcpStream 在 read_to_string 上被阻止