Tim
Tim

Reputation: 7421

Dynamic Image caching handler.ashx not caching

I'm taking over a project which uses a handler.ashx to auto-generate different sized versions of an image if they don't already exist. Additionally it should serve existing images and cache them in the clients browser. however all requests to the image return a 200 thus not caching.

When I use fiddler to see the requests the initial response of the image shows

InitialResponse after receiving the image the second request secondrequest secondresponse

<%@ WebHandler Language="VB" CodeBehind="GenericHandler.ashx.vb" Class=".GenericHandler" %>

Imports System.IO
Imports System.Web
Imports System.Web.Services
Imports System.Web.Script.Serialization
Imports System.Globalization

Public Class GenericHandler
    Implements System.Web.IHttpHandler, System.Web.SessionState.IRequiresSessionState

    Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest

        RequestHandler(context)

    End Sub
    Private Sub RequestHandler(ByVal context As HttpContext)
        Select Case context.Request.HttpMethod
            Case "GET"
                GetFile(context)
            Case Else
                context.Response.ClearHeaders()
                context.Response.StatusCode = 405
        End Select
    End Sub

    Private Sub GetFile(ByVal context As HttpContext)
        Dim strAssetId As String = context.Request("asset")
        Dim strSize As String = context.Request("size")
        Dim fileName As String = getAssetName(strAssetId)
        Dim internalFile As String = CalculateFileName(context, fileName)
        Dim refresh As TimeSpan = New TimeSpan(1, 0, 0, 0) '1 day cache
        Dim encode As Boolean = context.Request("encode") = "1"

        'we have already created the file
        If File.Exists(internalFile) Then

            'has the browser already recieved a cached version
            If Not String.IsNullOrEmpty(context.Request.Headers("If-Modified-Since")) Then
                Dim provider As CultureInfo = CultureInfo.InvariantCulture
                Dim lastMod As DateTime = DateTime.ParseExact(context.Request.Headers("If-Modified-Since"), "r", provider).ToLocalTime()

                'cached but is it within the expiry range                
                If lastMod < DateTime.Now.Add(refresh) Then
                    context.Response.StatusCode = 304
                    Return
                End If
            End If
        Else
            'this size of image didn't exist so create it.
            GenerateFile(context, internalFile)

        End If
        context.Response.ClearContent()
        context.Response.AddHeader("Content-Disposition", "attachment; filename=""" + fileName + """")
        context.Response.Cache.SetExpires(DateTime.Now.Add(refresh))
        context.Response.Cache.SetMaxAge(refresh)
        context.Response.Cache.SetCacheability(HttpCacheability.Public)
        context.Response.Cache.SetValidUntilExpires(True)
        context.Response.ContentType = "image/png"

        If encode Then
            context.Response.Write(ImageBase64Encoder.Encode(internalFile))
        Else
            context.Response.WriteFile(internalFile)
        End If
    End Sub

    Private Function CalculateFileName(ByVal context As HttpContext, fileName)
        'calculates the filename of the requestedfilesize
    End Function

    Private Sub GenerateFile(ByVal context As HttpContext, internalFile As String)
        'generates the correct sized version of the original image
    End Sub


    ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
        Get
            Return False
        End Get
    End Property

End Class

Upvotes: 0

Views: 1140

Answers (1)

marapet
marapet

Reputation: 56496

The request headers of your second request do not contain the If-Modified-Since header you're checking in your code.

Why not?

Because the first response does not contain a Last-Modified header.

How to set the Last-Modified header ?

You can use: context.Response.Cache.SetLastModified(myfile.LastWriteTime);

Upvotes: 1

Related Questions