如何使用ASP.NET MVC上的IHttpHandler从azure存储帐户返回图像

时间:2015-08-27 08:58:58

标签: azure azure-storage ihttphandler

如果用户有权通过某种数据库驱动的算法查看图像,我有一个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图像请求的请求时间细分: enter image description here

1 个答案:

答案 0 :(得分:1)

您的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存储中下载而不是从本地服务器下载而没有一些更改性能。