How to use output caching on .ashx handler

后端 未结 5 1817
遥遥无期
遥遥无期 2020-12-02 13:40

How can I use output caching with a .ashx handler? In this case I\'m doing some heavy image processing and would like the handler to be cached for a minute or so.

Al

相关标签:
5条回答
  • 2020-12-02 14:10

    I used the following with success and thought it worthwhile to post here .

    Manually controlling the ASP.NET page output cache

    From http://dotnetperls.com/cache-examples-aspnet

    Setting cache options in Handler.ashx files

    First, you can use HTTP handlers in ASP.NET for a faster way to server dynamic content than Web Form pages. Handler.ashx is the default name for an ASP.NET generic handler. You need to use the HttpContext parameter and access the Response that way.

    Sample code excerpted:

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

    C# to cache response for 1 hour

    using System;
    using System.Web;
    
    public class Handler : IHttpHandler {
    
        public void ProcessRequest (HttpContext context) {
            // Cache this handler response for 1 hour.
            HttpCachePolicy c = context.Response.Cache;
            c.SetCacheability(HttpCacheability.Public);
            c.SetMaxAge(new TimeSpan(1, 0, 0));
        }
    
        public bool IsReusable {
            get {
                return false;
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-02 14:18

    There are some good sources but you want to cache you processing server side and client-side.

    Adding HTTP headers should help in the client side caching

    here are some Response headers to get started on..

    You can spend hours tweaking them until you get the desired performance

    //Adds document content type
    context.Response.ContentType = currentDocument.MimeType;
    context.Response.Cache.SetCacheability(HttpCacheability.Public);
    context.Response.Cache.SetExpires(DateTime.Now.AddMinutes(10));
    context.Response.Cache.SetMaxAge(new TimeSpan(0,10,0)); 
    context.Response.AddHeader("Last-Modified", currentDocument.LastUpdated.ToLongDateString());
    
    // Send back the file content
    context.Response.BinaryWrite(currentDocument.Document);
    

    As for server side caching that is a different monster... and there are plenty of caching resources out there...

    0 讨论(0)
  • 2020-12-02 14:20

    The solution with the OutputCachedPage works fine, however at a price of the performance, since you need to instantiate an object derived from the System.Web.UI.Page base class.

    A simple solution would be to use the Response.Cache.SetCacheability, as suggested by some of the above answers. However for the response to be cached at the server (inside Output Cache) one needs to use HttpCacheability.Server, and set a VaryByParams or VaryByHeaders (note that when using VaryByHeaders URL can't contain a query string, since the cache will be skipped).

    Here's a simple example (based on https://support.microsoft.com/en-us/kb/323290):

    <%@ WebHandler Language="C#" Class="cacheTest" %>
    using System;
    using System.Web;
    using System.Web.UI;
    
    public class cacheTest : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            TimeSpan freshness = new TimeSpan(0, 0, 0, 10);
            DateTime now = DateTime.Now; 
            HttpCachePolicy cachePolicy = context.Response.Cache;
    
            cachePolicy.SetCacheability(HttpCacheability.Public);
            cachePolicy.SetExpires(now.Add(freshness));
            cachePolicy.SetMaxAge(freshness);
            cachePolicy.SetValidUntilExpires(true);
            cachePolicy.VaryByParams["id"] = true;
    
            context.Response.ContentType = "application/json";
            context.Response.BufferOutput = true;
    
            context.Response.Write(context.Request.QueryString["id"]+"\n");
            context.Response.Write(DateTime.Now.ToString("s"));
        }
    
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
    

    Hint: you monitor the caching in the Performance Counters "ASP.NET Applications__Total__\Output Cache Total".

    0 讨论(0)
  • 2020-12-02 14:22

    Old, question but the answer didn't really mentioned the server-side handling.

    As in the winning answer, I would use this for the client side:

    context.Response.Cache.SetCacheability(HttpCacheability.Public);
    context.Response.Cache.SetExpires(DateTime.Now.AddMinutes(10));
    context.Response.Cache.SetMaxAge(TimeSpan.FromMinutes(10)); 
    

    and for the server side, since you are using a ashx instead of a web page, I'm assuming that you are directly writing the output to the Context.Response.

    In that case you could use something like this (in this case I want to save the response based on parameter "q", and Im using a sliding window expiration)

    using System.Web.Caching;
    
    public void ProcessRequest(HttpContext context)
    {
        string query = context.Request["q"];
        if (context.Cache[query] != null)
        {
            //server side caching using asp.net caching
            context.Response.Write(context.Cache[query]);
            return;
        }
    
        string response = GetResponse(query);   
        context.Cache.Insert(query, response, null, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(10)); 
        context.Response.Write(response);
    }
    
    0 讨论(0)
  • 2020-12-02 14:23

    you can use like this

    public class CacheHandler : IHttpHandler
        {
    
            public void ProcessRequest(HttpContext context)
            {
                OutputCachedPage page = new OutputCachedPage(new OutputCacheParameters
                {
                    Duration = 60,
                    Location = OutputCacheLocation.Server,
                    VaryByParam = "v"
                });
                page.ProcessRequest(HttpContext.Current);
                context.Response.Write(DateTime.Now);
            }
    
            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()
                {
                    // when you put the <%@ OutputCache %> directive on a page, the generated code calls InitOutputCache() from here
                    base.FrameworkInitialize();
                    InitOutputCache(_cacheSettings);
                }
            }
        }
    
    0 讨论(0)
提交回复
热议问题