April 2008
Posted on the 7th at 9:59 PM CST
Support CSS Naked Day Redux
FiledFiled under ASP.NET, CSS

A couple days ago I made a blog post about a simple HTTP handler written in ASP.NET. The purpose? To spit out 404 errors for .css file requests on CSS Naked Day. That handler will undoubtedly work great, but it does have one minor maintenance-related flaw. Each year you will have to update the constant date value to be accurate. Granted, that is a simple task, but it still requires time and a little bit of effort. Dustin Diaz left a comment notifying me of a nice JSON file sitting out on GoogleCode that I could tap into programmatically to determine the official date of CSS Naked Day. And that eliminates the maintenance flaw. Brilliant! So I went ahead and re-wrote the handler to call that JSON file and store the value in cache. There are some constant variables declared at the top that you can modify to your liking. Here is the code…

Imports System.IO
Imports System.Net
Imports System.Web
Imports System.Web.Caching

Public Class Naked
    Implements IHttpHandler

    Private Const NAKED_DAY_API As String = "http://php-naked-day-api.googlecode.com/files/config.json"
    Private Const NAKED_DAY_DEFAULT As Integer = 9 'The default day to use if the API call failed or was invalid (paranoia)
    Private Const CACHE_KEY As String = "Css.NakedDay"
    Private Const CACHE_LIFETIME As Integer = 24 'Number of hours to store the value in Cache

    Public Sub ProcessRequest(ByVal context As System.Web.HttpContext) Implements IHttpHandler.ProcessRequest
        Dim Path As String = context.Request.PhysicalPath

        With context.Response
            If File.Exists(Path) AndAlso Date.Today <> GetNakedDay(context.Cache) Then
                .ContentEncoding = Encoding.UTF8
                .ContentType = "text/css"
                .WriteFile(Path, False)
            Else
                .StatusCode = 404
                .End()
                .Close()
            End If
        End With
    End Sub

    Private Function GetNakedDay(ByRef Cache As Cache) As Date
        Const MONTH As Integer = 4
        Dim NakedDay As Date

        If Cache.Item(CACHE_KEY) Is Nothing Then
            Dim Token As New Regex("""day"" : (\d{1,2})")
            Dim Api As String

            NakedDay = New Date(Date.Now.Year, MONTH, NAKED_DAY_DEFAULT)

            Try
                Using Client As New WebClient()
                    Api = Client.DownloadString(NAKED_DAY_API)
                End Using
            Catch ex As WebException
                Api = String.Empty
            End Try

            If Not String.IsNullOrEmpty(Api) AndAlso Token.IsMatch(Api) Then
                Dim Hold As String() = Token.Matches(Api).Item(0).Value.Split(":")
                NakedDay = New Date(Date.Now.Year, MONTH, CInt(Hold(1).Trim()))

                'Only add the value to cache if the API call was successful
                Cache.Add(CACHE_KEY, NakedDay, Nothing, Date.Now.AddHours(CACHE_LIFETIME), Cache.NoSlidingExpiration, CacheItemPriority.Normal, Nothing)
            End If
        Else
            NakedDay = Date.Parse(Cache.Get(CACHE_KEY))
        End If

        Return NakedDay
    End Function

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


To implement this handler into your ASP.NET web site, simply modify the <httpHandlers> element within <system.web> in the web.config file as illustrated here…

<system.web>
  <httpHandlers>
    <add verb="*" path="*.css" type="Naked" validate="false"/>
  </httpHandlers>
</system.web>


That's it. Enjoy!

Comments (4)
Permalink Comment from Sam on May 28th, 2008 at 12:12 AM
Doesn't this also require mapping .css requests to the asp.net runtime in IIS?

Also is the Josh Stodola (ALF fan) that seems to have had his account on the asp.net forums disabled. Did u flame one too many MSFTs?

http://forums.asp.net/user/Profile.aspx?UserID=702405
Permalink Comment from Josh StodolaEmail on May 28th, 2008 at 7:32 AM
You should not have to do anything in IIS. And yes, it's me.
Permalink Comment from Sam on May 30th, 2008 at 1:35 AM
I thought CSS files were served by IIS directly. If that's true then your handler will never know about the request. At least that's the case for IIS6.
Permalink Comment from Josh StodolaEmail on May 30th, 2008 at 9:36 AM
Sam, my apologies, you are absolutely correct. You do have to configure IIS to pass files with a .css file extention to the ASP.NET ISAPI filter. When I integrated this handler into my blog, I did not have to do this because I had already done it in the past to accomodate a different handler that I use to remove whitespace from my CSS files. I will update the post later tonight to include this info. Thanks alot!

Guess What?

There are a few basic guidelines you should be aware of before leaving a comment…

  • If you choose to display your email address, it will not be detected by spam bots
  • Comments are limited to 3,000 characters; so far you have used none of them
  • HTML will be encoded; links and line breaks will be converted automatically
  • Comments containing five or more links will be subject to moderation

Have Your Say

← Answer this to prove you are human
 
 

Chill Out…

No Trackbacks