How do use change the default http handler in ASP,NET similar to ISAPI filter ?

Discussion in 'ASP .Net' started by Anonieko Ramos, May 12, 2004.

  1. Answer. Use IHttpHandler.
    thanks Ro ry for coming up with this code.
    It processes css file to add variables. neat idea

    using System;
    using System.IO;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Web;
    using System.Web.Caching;

    namespace CssHandler {
    public class CssHandler : IHttpHandler {

    // We're going to use a constant for the name of our Cache object
    variable.
    //
    // I think that using constants for this purpose is better than
    using string
    // literals.
    //
    // For example, which of the following would be easier to maintain:
    //
    // Cache["Some really long and error prone string"] = someValue;
    // - or -
    // Cache[SOME_CONSTANT] = someValue;
    //
    // I think I've made my point.
    private const string CSS_CACHE_BODY = "Css.FileBody";

    // We don't really need this constructor. It's here for decorative
    purposes only -
    // Kind of like the plastic grass you get with sushi.
    public CssHandler() {}

    // IHttpHandler method - Ignore this one. These aren't the droids
    you're looking for.
    public bool IsReusable { get { return false; } }

    // IHttpHandler method - This is the entry point for our handler.
    public void ProcessRequest( System.Web.HttpContext context ) {

    try {
    // Grab the filename that was requested by the browser. Since this
    handler is
    // for CSS documents, the filename is probably going to be
    something like
    // "styles.css" - It could, of course, be any other CSS document
    in the system.
    // "styles.css" was just an example, OK? Get over it.
    string file = context.Request.PhysicalPath;

    // Does the file even exist? If it doesn't, then let's just forget
    about the whole
    // thing. We've been had. You can add your own error processing
    here, such as
    // returning a 404 error to the browser. I'd do it, but I'm half
    dead from sleep
    // deprivation in Connecticut, and it isn't really the focus of
    this sample code.
    if (!File.Exists(file))
    return;

    // We're going to store the process CSS file in the following
    variable named "body."
    //
    // Notice that when we try to pull the processed CSS from the
    cache, we're appending
    // the file name of the stylesheet we're currently processing to
    the "CSS_CACHE_BODY"
    // variable. This is so that our handler can deal with multiple
    stylesheets. If we didn't
    // do this, then each stylesheet to be processed would overwrite
    the previous one in
    // the cache. So many bad things would come of this that I prefer
    not to think about it.
    // Hence using the file name as a qualifier to create a
    unique(ish) key.

    string body = string.Empty;

    if (context.Cache[CSS_CACHE_BODY + file] != null)
    body = context.Cache[CSS_CACHE_BODY + file].ToString();
    //string body = context.Cache[CSS_CACHE_BODY + file] != null ?
    // context.Cache[CSS_CACHE_BODY].ToString() : string.Empty;

    // If "body" is equal to string.Empty, then it means we either
    haven't processed
    // the stylesheet yet, or that it's been blown out of the cache.
    if (body == string.Empty) {

    // Read the contents of the file into a variable named "body."
    StreamReader reader = new StreamReader(file);
    body = reader.ReadToEnd();
    reader.Close();

    // Strip the comments from the CSS document. If we don't, then
    they'll get in the
    // way later on when we perform the actual processing.
    body = StripComments(body);

    // Now that we've stripped the comments, we can go ahead and
    process the CSS.
    body = ProcessStyleSheet(body);

    // Almost time to stuff the contents of the "body" variable into
    the Cache.
    //
    // First, we're going to create a CacheDependency object that
    we'll associate
    // with our Cache item (the processed CSS body). If the CSS file
    is changed at
    // any time, the cached object will be vaporized, and null will
    be returned in
    // the "if" test you saw a few lines ago, causing this code to
    run again.
    //
    // If you'd like a detailed explanation of the CacheDependency
    object, then I
    // can recommend the world's greatest CacheDependency tutorial
    (which I
    // happened to write): http://neopoleon.com/blog/posts/1976.aspx
    //
    // Note that I'm just kidding about all this "world's greatest"
    crap. You have
    // to find ways to make yourself feel good about sitting at home
    on a Friday
    // night (Saturday morning now) while putting together sample
    code. It's fun
    // and all, but something tells me that I should be out getting
    drunk and trying
    // to get it on with a sofa.
    CacheDependency cd = new CacheDependency(file);

    // We've performed all the processing necessary, so let's store
    this stylesheet
    // in the cache.
    //
    // Note that when using a CacheDependency, you use the "Insert"
    method of the
    // Cache object. I understand that some of you might not like
    this, but I don't
    // like mushrooms or pork, and I have to co-exist with them - we
    all have to
    // do our part to be tolerant of the world around us.
    context.Cache.Insert(CSS_CACHE_BODY + file, body, cd);
    }

    // Whether we've had to process a file or not, we have to dump its
    contents to the
    // Response stream. That's what we're doing here.
    //
    // This is the last step in the process. Once it's complete, our
    handler's job
    // is finished.
    context.Response.Write(body);
    } catch (Exception ex) {
    context.Response.Write(ex.Message);
    }
    }

    // This is the method that we're using (as its name implies) to
    strip comments from
    // the body of the CSS document.
    //
    // There's some regular expressions stuff in here. A discussion of
    regular expressions
    // is beyond the scope of this tutorial, so just pretend like you
    never saw this.
    private string StripComments( string body ) {
    body = Regex.Replace(body, @"/\*.+?\*/", "",
    RegexOptions.Singleline);
    return body;
    }

    // This where the real work is getting done. One of our modern
    "@define" stylesheets
    // comes in this end, and goes out the other in a format that a
    browser will understand.
    private string ProcessStyleSheet( string body ) {
    // I made the decision to use regular expressions to extract the
    @define block
    // from the rest of the CSS document.
    //
    // If you don't understand regular expressions, then I can
    wholeheartedly
    // recommend Dan Appleman's guide to .NET regular expressions. It's
    short,
    // available online, and to the point.
    Regex regex = new Regex(@"@define\s*{(?<defines>[^}]*)}",
    RegexOptions.Singleline);
    Match match = regex.Match(body);

    // Did our regular expression find a @define block? If not, then
    let's just return
    // the stylesheet unmodified. No reason to hop through the rest of
    the code if
    // there's nothing to do, eh?
    if (!match.Success)
    return body;

    // The regular expression ought to have isolated the variable
    name/value pairs
    // in the @define block. We're going to separate these key/value
    pairs out into
    // a string array so that we can manipulate them individually.
    string[] lines = match.Groups["defines"].Value.Split(new char[]
    {';'});

    // We're going to be performing some string manipulation on the CSS
    document
    // body. Like good little coders, we're NOT going to do this with a
    string -
    // Rather, we're going to do it with a StringBuilder.
    StringBuilder sb = new StringBuilder(body);

    // Iterate through each element of the "lines" array. Each string
    in the "lines"
    // array should consist of one key/value pair.
    foreach (string line in lines) {

    // Did we get a blank line? If so, then let's move onto the next.
    if (string.Empty == line.Trim())
    continue;

    // The CSS assignment operator is the colon (':') - We'll split
    the line on
    // this character, resulting in an array with two elements. The
    first
    // element will be the variable name, while the second will be the
    variable
    // value.
    string[] tokens = line.Split(new char[] {':'});
    string variableName = tokens[0].Trim();
    string variableValue = tokens[1].Trim();

    // Now that we've extracted the variable name/value from the line,
    we can
    // replace all of the instances of the variable name in the rest
    of the
    // CSS document with the variable's value. This is where all the
    "magic"
    // happens.
    sb.Replace("@" + variableName, variableValue);
    }

    // All done. Return our processed stylesheet to the caller. Not so
    bad, eh?
    return sb.ToString();
    }

    }
    }


    ------------
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>

    <system.web>

    ........

    <!-- Pssssst - this is the stuff we have to add to the config file
    to map CSS files to
    the custom handler -->
    <httpHandlers>
    <add verb="GET" path="*.css" type="CssHandler.CssHandler,
    CssHandler" />
    </httpHandlers>

    </system.web>

    </configuration>
     
    Anonieko Ramos, May 12, 2004
    #1
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Michael Shutt
    Replies:
    0
    Views:
    818
    Michael Shutt
    Jun 26, 2003
  2. Jeremy
    Replies:
    1
    Views:
    662
    jeremy
    Aug 29, 2003
  3. Guoqi Zheng

    ISAPI filter or http module

    Guoqi Zheng, Jan 27, 2005, in forum: ASP .Net
    Replies:
    10
    Views:
    1,055
    Ben Lovell
    Jan 27, 2005
  4. Willie Ferguson

    Re: ISAPI filter or http module

    Willie Ferguson, Jan 28, 2005, in forum: ASP .Net
    Replies:
    0
    Views:
    419
    Willie Ferguson
    Jan 28, 2005
  5. Dmitry Duginov

    GAC + Http module (ISAPI filter) problem

    Dmitry Duginov, Feb 25, 2005, in forum: ASP .Net
    Replies:
    2
    Views:
    711
    Dmitry Duginov
    Feb 26, 2005
Loading...

Share This Page