【发布时间】:2020-01-30 06:53:32
【问题描述】:
我有一个使用 C# 编写的名为“存储”的基于 ASP.NET Core 的 Web API。这个应用程序旨在为许多带有图像的网络应用程序提供服务。使用我拥有的其他应用程序可以使用 HTTP 请求从存储中请求图像。
为了从辅助/消费应用与我的存储应用交互,我创建了一个自定义文件提供程序实现,允许我像这样访问这些图像
public class MyCustomImagesProvider : IFileProvider
{
private readonly IHttpClientFactory ClientFactory;
public MyCustomImagesProvider(IHttpClientFactory clientFactory)
{
ClientFactory = clientFactory;
}
public IFileInfo GetFileInfo(string subpath)
{
try
{
var client = ClientFactory.CreateClient("client-name");
Uri url = new Uri("https://storage.mydomain.com", $"api/files/get?name={subpath}");
var result = client.GetAsync(url).Result;
result.EnsureSuccessStatusCode();
string filename = Path.GetFileName(subpath);
DateTime lastModifiedAt = (result.Content.Headers.LastModified?.DateTime) ?? DateTime.Now;
var stream = result.Content.ReadAsStreamAsync().Result;
return new MyCustomFileInfo(stream, filename, lastModifiedAt);
}
catch
{
}
return new MyCustomFileInfo
{
Exists = false
};
}
public IDirectoryContents GetDirectoryContents(string subpath) => throw new NotImplementedException();
public IChangeToken Watch(string filter) => throw new NotImplementedException();
}
我的一些应用只需要图像的缩略图,而其他应用需要全尺寸和/或图像的缩略图。稍后,对于某些应用程序,我什至可能还需要一个中等大小的图像(可能是同一个图像的 4 个不同大小。)磁盘空间限制正在成为一个问题,因为我必须将同一个图像复制到多个文件中(每个大小一个)以容纳我的所有应用程序。
换句话说,如果我有一个名为“abc_fullsize.jpg”的文件,那么我需要创建和存储“abc_thumbnail.jpg”和需要大量磁盘空间的“abc_midside.jpg”。
问题
动态创建这些图像而不是在办公桌上创建它们是否有效?
我想我会有一个ThumbnailImageProvider、MidsizeImageProvider 和 FullsizeImageProvider,每个都会发送存储应用所需的最大尺寸,存储应用会从桌面读取全尺寸图像,然后回复调整大小的图像。这是ThumbnailImageProvider的示例
public class ThumbnailImageProvider : IFileProvider
{
private readonly IHttpClientFactory ClientFactory;
public ThumbnailImageProvider(IHttpClientFactory clientFactory)
{
ClientFactory = clientFactory;
}
public IFileInfo GetFileInfo(string subpath)
{
try
{
var client = ClientFactory.CreateClient("client-name");
// Note the max-width=250 parameter here would tell the API that I need this image recreated on the fly with max width of 250.
Uri url = new Uri("https://storage.mydomain.com", $"api/files/get?name={subpath}&maxWidth=250");
var result = client.GetAsync(url).Result;
result.EnsureSuccessStatusCode();
string filename = Path.GetFileName(subpath);
DateTime lastModifiedAt = (result.Content.Headers.LastModified?.DateTime) ?? DateTime.Now;
var stream = result.Content.ReadAsStreamAsync().Result;
return new MyCustomFileInfo(stream, filename, lastModifiedAt);
}
catch
{
}
return new MyCustomFileInfo
{
Exists = false
};
}
public IDirectoryContents GetDirectoryContents(string subpath) => throw new NotImplementedException();
public IChangeToken Watch(string filter) => throw new NotImplementedException();
}
api/files/get 端点上的操作方法将响应以下操作
[HttpGet("get")]
public IActionResult Get(string name, int? maxWidth)
{
IFileInfo fileInfo = FileProvider.GetFileInfo(name);
if (!fileInfo.Exists)
{
return NotFound();
}
if(maxWidth.HasValue && maxWidth > 1)
{
Image image = ImageProcessor.GetResizedImage(fileInfo.CreateReadStream(), maxWidth.Value, out ImageFormat imageFormat);
using var memoryStream = new MemoryStream();
image.Save(memoryStream, imageFormat);
string extension = Path.GetExtension(fileInfo.Name);
string rawFilename = Path.GetFileNameWithoutExtension(fileInfo.Name);
string filename = $"{rawFilename}-{maxWidth}{extension}";
return File(memoryStream, "image/jpeg", filename, fileInfo.LastModified, null);
}
return File(fileInfo.CreateReadStream(), "image/jpeg", fileInfo.Name, fileInfo.LastModified, null);
}
【问题讨论】:
标签: c# http asp.net-core asp.net-core-mvc asp.net-core-webapi