Question

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

Exception

Was it helpful?

Solution

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);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top