By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,454 Members | 1,803 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,454 IT Pros & Developers. It's quick & easy.

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

P: n/a
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>
Nov 18 '05 #1
Share this question for a faster answer!
Share on Google+

This discussion thread is closed

Replies have been disabled for this discussion.