I am trying to save and retrieve an Image from HTTPRuntime Cache but I am getting an exception. I am able to save a stream to cache but when I try to retrieve it I get an exception saying:
the request was aborted. The connection was closed unexpectedly
Here is my code:
public void ProcessRequest(HttpContext context)
{
string courseKey = context.Request.QueryString["ck"];
string objKey = context.Request.QueryString["file"];
if(HttpRuntime.Cache[objKey] !=null)
{
using (Stream stream = (Stream)HttpRuntime.Cache[objKey]) // here is where I get an exception
{
var buffer = new byte[8000];
var bytesRead = -1;
while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
{
context.Response.OutputStream.Write(buffer, 0, bytesRead);
}
}
return;
}
var response = Gets3Response(objKey, courseKey, context);
if (response != null)
{
using (response)
{
var MIMEtype = response.ContentType;
context.Response.ContentType = MIMEtype;
var cacheControl = context.Response.CacheControl;
HttpRuntime.Cache.Insert(objKey, response.ResponseStream, null, DateTime.UtcNow.AddMinutes(20), Cache.NoSlidingExpiration);
using (Stream responseStream = response.ResponseStream)
{
var buffer = new byte[8000];
var bytesRead = -1;
while ((bytesRead = responseStream.Read(buffer, 0, buffer.Length)) > 0)
{
context.Response.OutputStream.Write(buffer, 0, bytesRead);
}
}
}
}
}
And here is the exception I am getting
This code is pretty confusing. First, you are caching response.ResponseStream
, but that has been wrapped in a using
block. So by the time you get to HttpRuntime.Cache.Insert, response.ResponseStream is already disposed and closed. Hence the error.
You should not be caching a stream. For one thing, once you put a distributed cache service in place, your approach will be impossible. You need to refactor this. Consider:
public class CacheAsset
{
public string FileName { get; set; }
public string ContentType { get; set; }
public byte[] Content { get; set; }
}
CacheAsset GetAsset(HttpContext context)
{
string courseKey = context.Request.QueryString["ck"];
string objKey = context.Request.QueryString["file"];
var asset = context.Cache[objKey] as CacheAsset;
if (asset != null) return asset;
using (var response = Gets3Response(objKey, courseKey, context))
using (var stream = new MemoryStream())
{
var buffer = new byte[8000];
var read = 0;
while ((read = response.ReponseStream.Read(buffer, 0, buffer.Length)) > 0)
{
stream.Write(buffer, 0, read);
}
asset = new CacheAsset
{
FileName = objKey,
ContentType = reponse.ContentType,
Content = stream.ToArray()
};
context.Cache.Insert(objKey, asset, null, DateTime.UtcNow.AddMinutes(20), Cache.NoSlidingExpiration);
}
return asset;
}
public void ProcessRequest(HttpContext context)
{
var asset = GetAsset(context);
context.Response.ContentType = asset.ContentType;
context.Response.BinaryWrite(asset.Content);
}