如何在 ASP.NET MVC 上使用 IHttpHandler return 来自 azure 存储帐户的图像
How to return images from azure storage account using IHttpHandler on ASP.NET MVC
我有一个 IHttpHandler 拦截图像请求和响应,如果用户有权通过某些数据库驱动的算法查看图像或不查看图像。
无论如何,在我将图像移至存储帐户之前,代码工作正常。与我从服务器的本地磁盘提供服务的时间相比,现在图像请求需要更多的时间。所以我想知道我是否在我的 IHttpHandler 代码上做错了什么,这就是问题的原因。
我请求像这样的图片:
<img src="/web-thumb/{userid}/{filename}.jpg">
我创建了一个路由定义:
routes.Add("ThumbnailsRoute",
new Route("web-thumb/{userid}/{filename}", new ThumbnailRouteHandler()));
这是我的缩略图处理程序:
public class ThumbnailRouteHandler : IRouteHandler
{
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
return new ThumbnailHandler(requestContext);
}
}
public class ThumbnailHandler : IHttpHandler
{
public ThumbnailHandler()
{
}
public ThumbnailHandler(RequestContext requestContext)
{
RequestContext = requestContext;
}
protected RequestContext RequestContext { get; set; }
public bool IsReusable
{
get { return false; }
}
public void ProcessRequest(HttpContext context)
{
// find physical path to image here.
var binResponse = Utility.GetFileContent("images/" + RequestContext.RouteData.Values["userid"] + "/thumbnail/" + RequestContext.RouteData.Values["filename"]);
context.Response.BinaryWrite(binResponse);
context.Response.End();
}
}
这里是 GetFileContent 辅助静态函数,用于将图像从存储器下载到字节数组:
public static byte[] GetFileContent(string fileName)
{
CloudBlobContainer container = getUserMediaContainer();
CloudBlockBlob blockBlob = container.GetBlockBlobReference(fileName);
if (blockBlob.Exists()) {
blockBlob.FetchAttributes();
long fileByteLength = blockBlob.Properties.Length;
byte[] fileContent = new byte[fileByteLength];
for (int i = 0; i < fileByteLength; i++)
{
fileContent[i] = 0x20;
}
blockBlob.DownloadToByteArray(fileContent, 0);
return fileContent;
}
return new byte[0];
}
private static CloudBlobContainer getUserMediaContainer()
{
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(System.Configuration.ConfigurationManager.ConnectionStrings["StorageConn"].ConnectionString);
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer userMedia = blobClient.GetContainerReference("user-media");
userMedia.CreateIfNotExists();
return userMedia;
}
这是两端35kb图片请求的请求时间明细:
您的 GetFileContent
函数正在创建与存储的连接并在每次调用时检查容器是否存在,我会保留对 CloudStorageAccount
的引用并在您的应用程序启动时检查容器是否存在.我假设没有理由在您的应用程序处于 运行.
时删除容器
例如
public static class Utility
{
// Keep ref to CloudStorageAccount
private static CloudStorageAccount _storageAccount;
private static CloudStorageAccount StorageAccount
{
get
{
if (_storageAccount == null)
{
_storageAccount = CloudStorageAccount.Parse(System.Configuration.ConfigurationManager.ConnectionStrings["StorageConn"].ConnectionString);
}
return _storageAccount;
}
}
static Utility()
{
// Just check the container exists when app starts or on first download
CloudBlobClient blobClient = StorageAccount.CreateCloudBlobClient();
CloudBlobContainer userMedia = blobClient.GetContainerReference("user-media");
userMedia.CreateIfNotExists();
}
public static byte[] GetFileContent(string fileName)
{
CloudBlobClient blobClient = StorageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("user-media");
CloudBlockBlob blockBlob = container.GetBlockBlobReference(fileName);
if (blockBlob.Exists())
{
blockBlob.FetchAttributes();
long fileByteLength = blockBlob.Properties.Length;
byte[] fileContent = new byte[fileByteLength];
blockBlob.DownloadToByteArray(fileContent, 0);
return fileContent;
}
return new byte[0];
}
}
你没有说下载时间的差异有多大,但我假设你不希望从 blob 存储而不是从本地服务器下载而不改变性能。
我有一个 IHttpHandler 拦截图像请求和响应,如果用户有权通过某些数据库驱动的算法查看图像或不查看图像。 无论如何,在我将图像移至存储帐户之前,代码工作正常。与我从服务器的本地磁盘提供服务的时间相比,现在图像请求需要更多的时间。所以我想知道我是否在我的 IHttpHandler 代码上做错了什么,这就是问题的原因。
我请求像这样的图片:
<img src="/web-thumb/{userid}/{filename}.jpg">
我创建了一个路由定义:
routes.Add("ThumbnailsRoute",
new Route("web-thumb/{userid}/{filename}", new ThumbnailRouteHandler()));
这是我的缩略图处理程序:
public class ThumbnailRouteHandler : IRouteHandler
{
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
return new ThumbnailHandler(requestContext);
}
}
public class ThumbnailHandler : IHttpHandler
{
public ThumbnailHandler()
{
}
public ThumbnailHandler(RequestContext requestContext)
{
RequestContext = requestContext;
}
protected RequestContext RequestContext { get; set; }
public bool IsReusable
{
get { return false; }
}
public void ProcessRequest(HttpContext context)
{
// find physical path to image here.
var binResponse = Utility.GetFileContent("images/" + RequestContext.RouteData.Values["userid"] + "/thumbnail/" + RequestContext.RouteData.Values["filename"]);
context.Response.BinaryWrite(binResponse);
context.Response.End();
}
}
这里是 GetFileContent 辅助静态函数,用于将图像从存储器下载到字节数组:
public static byte[] GetFileContent(string fileName)
{
CloudBlobContainer container = getUserMediaContainer();
CloudBlockBlob blockBlob = container.GetBlockBlobReference(fileName);
if (blockBlob.Exists()) {
blockBlob.FetchAttributes();
long fileByteLength = blockBlob.Properties.Length;
byte[] fileContent = new byte[fileByteLength];
for (int i = 0; i < fileByteLength; i++)
{
fileContent[i] = 0x20;
}
blockBlob.DownloadToByteArray(fileContent, 0);
return fileContent;
}
return new byte[0];
}
private static CloudBlobContainer getUserMediaContainer()
{
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(System.Configuration.ConfigurationManager.ConnectionStrings["StorageConn"].ConnectionString);
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer userMedia = blobClient.GetContainerReference("user-media");
userMedia.CreateIfNotExists();
return userMedia;
}
这是两端35kb图片请求的请求时间明细:
您的 GetFileContent
函数正在创建与存储的连接并在每次调用时检查容器是否存在,我会保留对 CloudStorageAccount
的引用并在您的应用程序启动时检查容器是否存在.我假设没有理由在您的应用程序处于 运行.
例如
public static class Utility
{
// Keep ref to CloudStorageAccount
private static CloudStorageAccount _storageAccount;
private static CloudStorageAccount StorageAccount
{
get
{
if (_storageAccount == null)
{
_storageAccount = CloudStorageAccount.Parse(System.Configuration.ConfigurationManager.ConnectionStrings["StorageConn"].ConnectionString);
}
return _storageAccount;
}
}
static Utility()
{
// Just check the container exists when app starts or on first download
CloudBlobClient blobClient = StorageAccount.CreateCloudBlobClient();
CloudBlobContainer userMedia = blobClient.GetContainerReference("user-media");
userMedia.CreateIfNotExists();
}
public static byte[] GetFileContent(string fileName)
{
CloudBlobClient blobClient = StorageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("user-media");
CloudBlockBlob blockBlob = container.GetBlockBlobReference(fileName);
if (blockBlob.Exists())
{
blockBlob.FetchAttributes();
long fileByteLength = blockBlob.Properties.Length;
byte[] fileContent = new byte[fileByteLength];
blockBlob.DownloadToByteArray(fileContent, 0);
return fileContent;
}
return new byte[0];
}
}
你没有说下载时间的差异有多大,但我假设你不希望从 blob 存储而不是从本地服务器下载而不改变性能。