我正在我的网站上显示我存储在数据库中的图像。从我的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缓存图像的方法,但所有这些示例都是如果您有实际文件而不是二进制数据。
答案 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
,表示输出缓存可以位于浏览器客户端(发出请求的位置),参与请求的代理服务器(或任何其他服务器)上,或者位于请求的服务器上已被处理。