存储在数据库中的MVC3缓存图像

时间:2012-02-14 17:36:07

标签: asp.net asp.net-mvc-3 caching razor

我正在我的网站上显示我存储在数据库中的图像。从我的Razor视图中我写了一条这样的行。

<img alt ="" src='@Url.Action("ShowImage",
            "Controller", new { imageID = Model.ImageID })'/>

被调用的函数看起来像这样。

    public ActionResult ShowImage(string imageID)
    {
        WebServiceClient client = new WebServiceClient();
        byte[] image = client.GetImage(Convert.ToInt64(imageID));
        if (image == null)
        {
            return new EmptyResult();
        }
        return File(image,"image/png");
    }

这很好用,但我的问题是,是否有可能以某种方式缓存这些图像。我已经看到了使用自定义HttpHandler缓存图像的方法,但所有这些示例都是如果您有实际文件而不是二进制数据。

2 个答案:

答案 0 :(得分:2)

以下是您可以使用的缓存说唱歌手:

public class CacheManager
{
    private static readonly string keyPrefix = typeof(CacheManager).FullName;
    private static readonly object syncLock = new object();

    private readonly Cache cache;

    public CacheManager(Cache cache)
    {
        this.cache = HttpRuntime.Cache;
    }

    public TValue Get<TValue>(string key)
    {
        return (TValue)HttpRuntime.Cache[MakeKey(key)];
    }

    public void Set<TValue>(string key, Func<TValue> value)
    {
        Set(key, null, null, null, value, null);
    }

    public void Set<TValue>(string key, DateTime timestamp, TValue value)
    {
        Set(key, timestamp, null, null, value, null);
    }

    public void Set<TValue>(string key, TimeSpan duration, TValue value)
    {
        Set(key, null, duration, null, value, null);
    }

    public void Set<TValue>(string key, TValue value, Action<bool> onRemoveCallback)
    {
        Set(key, null, null, null, value, onRemoveCallback);
    }

    public void Set<TValue>(string key, DateTime timestamp, TValue value, Action<bool> onRemoveCallback)
    {
        Set(key, timestamp, null, null, value, onRemoveCallback);
    }

    public void Set<TValue>(string key, TimeSpan duration, TValue value, Action<bool> onRemoveCallback)
    {
        Set(key, null, duration, null, value, onRemoveCallback);
    }

    public void Set<TValue>(string key, IEnumerable<string> fileDependencies, TValue value)
    {
        Set(key, null, null, fileDependencies, value, null);
    }

    public void Set<TValue>(string key, DateTime timestamp, IEnumerable<string> fileDependencies, TValue value)
    {
        Set(key, timestamp, null, fileDependencies, value, null);
    }

    public void Set<TValue>(string key, TimeSpan duration, IEnumerable<string> fileDependencies, TValue value)
    {
        Set(key, null, duration, fileDependencies, value, null);
    }

    public void Set<TValue>(string key, IEnumerable<string> fileDependencies, TValue value, Action<bool> onRemoveCallback)
    {
        Set(key, null, null, fileDependencies, value, onRemoveCallback);
    }

    public void Set<TValue>(string key, DateTime timestamp, IEnumerable<string> fileDependencies, TValue value, Action<bool> onRemoveCallback)
    {
        Set(key, timestamp, null, fileDependencies, value, onRemoveCallback);
    }

    public void Set<TValue>(string key, TimeSpan duration, IEnumerable<string> fileDependencies, TValue value, Action<bool> onRemoveCallback)
    {
        Set(key, null, duration, fileDependencies, value, onRemoveCallback);
    }

    public TValue GetOrCreate<TValue>(string key, Func<TValue> factory)
    {
        return GetOrCreate(key, null, null, null, factory, null);
    }

    public TValue GetOrCreate<TValue>(string key, DateTime timestamp, Func<TValue> factory)
    {
        return GetOrCreate(key, timestamp, null, null, factory, null);
    }

    public TValue GetOrCreate<TValue>(string key, TimeSpan duration, Func<TValue> factory)
    {
        return GetOrCreate(key, null, duration, null, factory, null);
    }

    public TValue GetOrCreate<TValue>(string key, Func<TValue> factory, Action<bool> onRemoveCallback)
    {
        return GetOrCreate(key, null, null, null, factory, onRemoveCallback);
    }

    public TValue GetOrCreate<TValue>(string key, DateTime timestamp, Func<TValue> factory, Action<bool> onRemoveCallback)
    {
        return GetOrCreate(key, timestamp, null, null, factory, onRemoveCallback);
    }

    public TValue GetOrCreate<TValue>(string key, TimeSpan duration, Func<TValue> factory, Action<bool> onRemoveCallback)
    {
        return GetOrCreate(key, null, duration, null, factory, onRemoveCallback);
    }

    public TValue GetOrCreate<TValue>(string key, IEnumerable<string> fileDependencies, Func<TValue> factory)
    {
        return GetOrCreate(key, null, null, fileDependencies, factory, null);
    }

    public TValue GetOrCreate<TValue>(string key, DateTime timestamp, IEnumerable<string> fileDependencies, Func<TValue> factory)
    {
        return GetOrCreate(key, timestamp, null, fileDependencies, factory, null);
    }

    public TValue GetOrCreate<TValue>(string key, TimeSpan duration, IEnumerable<string> fileDependencies, Func<TValue> factory)
    {
        return GetOrCreate(key, null, duration, fileDependencies, factory, null);
    }

    public TValue GetOrCreate<TValue>(string key, IEnumerable<string> fileDependencies, Func<TValue> factory, Action<bool> onRemoveCallback)
    {
        return GetOrCreate(key, null, null, fileDependencies, factory, onRemoveCallback);
    }

    public TValue GetOrCreate<TValue>(string key, DateTime timestamp, IEnumerable<string> fileDependencies, Func<TValue> factory, Action<bool> onRemoveCallback)
    {
        return GetOrCreate(key, timestamp, null, fileDependencies, factory, onRemoveCallback);
    }

    public TValue GetOrCreate<TValue>(string key, TimeSpan duration, IEnumerable<string> fileDependencies, Func<TValue> factory, Action<bool> onRemoveCallback)
    {
        return GetOrCreate(key, null, duration, fileDependencies, factory, onRemoveCallback);
    }

    public void Remove(string key)
    {
        HttpRuntime.Cache.Remove(MakeKey(key));
    }

    private static string MakeKey(string key)
    {
        Check.Argument.IsNotNullOrEmpty(key, "key");

        return keyPrefix + ":" + key;
    }

    private void Set<TValue>(string key, DateTime? timestamp, TimeSpan? duration, IEnumerable<string> fileDependencies, TValue value, Action<bool> onRemoveCallback)
    {
        string fullKey = MakeKey(key);

        lock (syncLock)
        {
            cache.Remove(fullKey);

            InsertInCache(fullKey, value, fileDependencies, timestamp, duration, onRemoveCallback);
        }
    }

    private TValue GetOrCreate<TValue>(string key, DateTime? timestamp, TimeSpan? duration, IEnumerable<string> fileDependencies, Func<TValue> factory, Action<bool> onRemoveCallback)
    {
        string fullKey = MakeKey(key);

        object value = cache.Get(fullKey);

        if (value == null)
        {
            lock (syncLock)
            {
                value = cache.Get(fullKey);

                if (value == null)
                {
                    value = factory();

                    if (value != null)
                    {
                        InsertInCache(fullKey, value, fileDependencies, timestamp, duration, onRemoveCallback);
                    }
                }
            }
        }

        return (TValue)value;
    }

    private void InsertInCache(string key, object value, IEnumerable<string> fileDependencies, DateTime? timestamp, TimeSpan? duration, Action<bool> onRemoveCallback)
    {
        Action<string, object, CacheItemRemovedReason> raiseOnRemoveCallback = (cacheKey, state, reason) => onRemoveCallback(reason == CacheItemRemovedReason.DependencyChanged);

        cache.Add(key, value, fileDependencies != null ? new CacheDependency(fileDependencies.ToArray()) : null, timestamp ?? Cache.NoAbsoluteExpiration, duration ?? Cache.NoSlidingExpiration, CacheItemPriority.Normal, onRemoveCallback != null ? new CacheItemRemovedCallback(raiseOnRemoveCallback) : null);
    }
}

您现在可以更改代码:

public ActionResult ShowImage(string imageID)
    {
        CacheManager cacheManager = new CacheManager();
        byte[] image = cacheManager.GetOrCreate(
                    imageID, //Cache Key
                    DateTime.Now.AddMinutes(20), //Will be in Cache for 20 min
                    () => {
                    WebServiceClient client = new WebServiceClient();
                    return client.GetImage(Convert.ToInt64(imageID));
        }); //Delegate to call if the cache is empty

        if (image == null)
        {
            return new EmptyResult();
        }
        return File(image,"image/png");
    }

答案 1 :(得分:1)

您可以尝试使用[OutputCache]属性修改控制器操作:

[OutputCache(Duration = 3600, VaryByParam = "imageID")]
public ActionResult ShowImage(string imageID)
{
    WebServiceClient client = new WebServiceClient();
    byte[] image = client.GetImage(Convert.ToInt64(imageID));
    if (image == null)
    {
        return new EmptyResult();
    }
    return File(image,"image/png");
}

您也可以决定使用Location属性缓存这些图像的位置。默认值为Any,表示输出缓存可以位于浏览器客户端(发出请求的位置),参与请求的代理服务器(或任何其他服务器)上,或者位于请求的服务器上已被处理。