[SOLVED] ASP.net cache ASHX file server-side

Issue

Given the generic handler:

<%@ WebHandler Language="C#" Class="autocomp" %>

using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI;

public class autocomp : IHttpHandler {

    public void ProcessRequest (HttpContext context) {

        context.Response.ContentType = "application/json";
        context.Response.BufferOutput = true;

        var searchTerm = (context.Request.QueryString["name_startsWith"] + "").Trim();

        context.Response.Write(searchTerm);
        context.Response.Write(DateTime.Now.ToString("s"));

        context.Response.Flush();
    }

    public bool IsReusable {
        get {
            return false;
        }
    }

}

How would I server side cache this file for 1 hour based on the name_startsWith query string parameter? With web user controls it’s easy:

<%@ OutputCache Duration="120" VaryByParam="paramName" %>

But I’ve been looking around for a while to do the same with a generic handler (ashx) file and can’t find any solutions.

Solution

With the code you’ve provided you’re telling the end user browser to cache the results for 30 minutes, so you aren’t doing any server side caching.

If you want to cache the results server side you’re probably looking for HttpRuntime.Cache. This would allow you to insert an item into a cache that is globally available. Then on the page load you would want to check the existence of the cached item, then if the item doesn’t exist or is expired in the cache, go to the database and retrieve the objects.

EDIT

With your updated code sample, I found https://stackoverflow.com/a/6234787/254973 which worked in my tests. So in your case you could do:

public class autocomp : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        OutputCachedPage page = new OutputCachedPage(new OutputCacheParameters
        {
            Duration = 120,
            Location = OutputCacheLocation.Server,
            VaryByParam = "name_startsWith"
        });

        page.ProcessRequest(HttpContext.Current);

        context.Response.ContentType = "application/json";
        context.Response.BufferOutput = true;

        var searchTerm = (context.Request.QueryString["name_startsWith"] + "").Trim();

        context.Response.Write(searchTerm);
        context.Response.Write(DateTime.Now.ToString("s"));
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
    private sealed class OutputCachedPage : Page
    {
        private OutputCacheParameters _cacheSettings;

        public OutputCachedPage(OutputCacheParameters cacheSettings)
        {
            // Tracing requires Page IDs to be unique.
            ID = Guid.NewGuid().ToString();
            _cacheSettings = cacheSettings;
        }

        protected override void FrameworkInitialize()
        {
            base.FrameworkInitialize();
            InitOutputCache(_cacheSettings);
        }
    }
}

Answered By – Steven V

Answer Checked By – Mary Flores (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *