Can I use Kentico CacheHelper to Cache an image served from a custom httphandler

Tracey Penberthy asked on November 30, 2017 18:32

Hi

I have a custom HttpHandler to serve dynamically created images (the images are processed based on url parameters).

Can I use the Kentico CacheHelper to store and request these images from cache once created and if so how?

Many Thanks

Tracey

Correct Answer

Vukasin Andjelic answered on December 1, 2017 14:08

ok try something like this. This is without cache dependency. But if u use cache dependency then u need to look for key in Debug -> Cache item, Dummy key second table

public void ProcessRequest(HttpContext context)
        {
            HttpResponse Response = context.Response;

            var imageurl = QueryHelper.GetText("imageUrl", String.Empty);

            //Get original Picture from Server
            string file = context.Server.MapPath("~" + imageurl);

            byte[] image = LoadImage(file);

            MemoryStream outStream = new MemoryStream(image);

            outStream.WriteTo(Response.OutputStream);
            outStream.Dispose();
            outStream.Close();
            //Set response type
            context.Response.ContentType = ".jpg";
            context.Response.End();

        }
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }

        private byte[] LoadImage(string file)
        {
           byte[] result = CacheHelper.GetItem("croppedimage|" + file) as byte[];

           if(result == null)
           {
           result = GetImage(file);
           CacheHelper.Add("croppedimage|" + file, result, null, DateTime.Now.AddMinutes(30),           System.Web.Caching.Cache.NoSlidingExpiration);
           }           
            return result;
        }
0 votesVote for this answer Unmark Correct answer

Recent Answers


Michal Samuhel answered on December 1, 2017 11:58

Hey Treacey,

You could use CacheHelper.Cache to cache results of your calls to images(see documentation page), so in other words to cache your binaries in handler code. Next time, when this method is called it first looks into cache for items and it serves cached items if it can be found based on its name.

However you will also need to take care about cache expiry and to set up cache dependecies in order to clear cache once image is updated. This however depends on your site setup (where are the images served, how are they updated and others)...

0 votesVote for this answer Mark as a Correct answer

Tracey Penberthy answered on December 1, 2017 12:59

Thanks Michal

That appears to work for me, although I cannot see my custom cache key in Debug > Cache items. Is there something else I need to do to see it here?

My cache key value takes the form of original image url appended with the crop coordinates

so for example "croppedimage|/BlankSite/media/WebsiteImages/tracey.jpg1010020500"

I am assuming that the caching is working because if I set the key value to a static value "croppedimage|1234" then the same image is always served.

Many thanks

Tracey

0 votesVote for this answer Mark as a Correct answer

Vukasin Andjelic answered on December 1, 2017 13:24

Hi Tracey Penberthy,

If u cached your item with CacheHelper, then you need to see it in Debug -> Cache items. Try to clear the cache in System -> Clear Cache. And then reload the page where you cache image, then take a look in to Debug -> Cache item.

0 votesVote for this answer Mark as a Correct answer

Tracey Penberthy answered on December 1, 2017 13:38

Hi Vukasin

I cleared my cache and refreshed the page but still it did not appear in Debug > Cache items

This is my code

public void ProcessRequest(HttpContext context)
        {
            HttpResponse Response = context.Response;

            var imageurl = QueryHelper.GetText("imageUrl", String.Empty);

            //Get original Picture from Server
            string file = context.Server.MapPath("~" + imageurl);

            byte[] image = CacheHelper.Cache(cs => LoadImage(cs, file), new CacheSettings(60, "croppedimage|" + GetCacheKeyValue()));

            MemoryStream outStream = new MemoryStream(image);

            outStream.WriteTo(Response.OutputStream);
            outStream.Dispose();
            outStream.Close();
            //Set response type
            context.Response.ContentType = ".jpg";
            context.Response.End();

        }
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }

        private byte[] LoadImage(CacheSettings cs, string file)
        {
            byte[] result = GetImage(file);
            if (cs.Cached)
            {
                cs.CacheDependency = CacheHelper.GetCacheDependency("croppedimage|" + GetCacheKeyValue());
            }
            return result;
        }
0 votesVote for this answer Mark as a Correct answer

Tracey Penberthy answered on December 1, 2017 15:26

Thank you Vukasin!

Your code snippet works great

Much appreciated!

0 votesVote for this answer Mark as a Correct answer

Vukasin Andjelic answered on December 1, 2017 15:56

I'm glad that I succeeded to help You

0 votesVote for this answer Mark as a Correct answer

   Please, sign in to be able to submit a new answer.