Skip navigation.

DOCTYPE In FrontPage?All recent postsTrimming Fat Of MSDN Magazine

Rewriting URLs And Validation Scare

Just recently I wrote about my affection for HttpHandlers and HttpModules. I wrote an HttpModule for this site which handles URL rewriting.

For example:

.../articles/css2_in_vsnet.aspx

gets rewritten to

.../articles/article.aspx?refName=css2_in_vsnet.aspx

I think it is much more professional to hide an ugly URL and present with a much cleaner one.

The module I employ checks every URL for a certain pattern with the help of a Regex (interestingly enough, Scott Mitchell described a much the same approach in his outstanding article URL Rewriting in ASP.NET).

Rewriting URLs comes at a price. It’s actually quite error prone. Also, there’s a nasty side-effect—when the server side form is rendered its action attribute reveals the real URL! If you postback the URL will appear in the browser’s address box. This alone might confuse people.

Scott proposed to create a custom control which replaces the standard server side form and omits the action tag altogether. In ASP.NET a server-side form can post only to itself. If you omit the action tag it won’t matter because it posts to itself anyway.

I also observed that ASP.NET was inserting the name of a non-existent folder which threw off my Regex rules and caused IIS to return a 404. Since this was a critical bug I decided to jump on it right away.

Instead of creating a custom form control I tweaked my XHTML page filter to remove the action tag from the outgoing stream.

The end result was pleasing: comments worked and navigation was flawless. As I tried to validate my pages I realized validation was broken because of the missing action tag! I practice what I preach which is why the hack had to go and I needed to devise a different solution.

The solution turned out to be quite simple. The same HttpModule that rewrites URLs hooks up another page filter (in addition to the XHTML one) which changes action tags they way they are supposed to be. Here’s an example:

<form method='post' action='article.aspx?refName=css2_in_vsnet'...

becomes

<form method='post' action='css2_in_vsnet.aspx'...

So far this technique has been working out quite well. In the meantime bear with me, please. :)

Some pages still don’t validate. For example, any page with comments trips the validator over an ASP.NET validation script. There’s not much I can do about it at the moment.

Comments

Comment permalink 1 Kiliman |
There is another option for rewriting the FORM action attribute.

Jesse Ezell creates a custom HtmlWriter and overrides the page's Render method().

http://weblogs.asp.net/jezell/archive/2004/03/15/90045.aspx

The use of RegEx seems kind of kludgey and inefficient to me.

Kiliman
Comment permalink 2 Milan Negovan |
It's a great post. A very detailed one. Thank you for sharing it.

I think his approach is more complicated and somewhat "intrusive". You have to commit to a form control and take care of dealing with attributes, etc. The HttpModule + page filter combo is an add-on. If you don't want to filter pages you simply remove the filter. If you don't want to rewrite URLs you simply unregister the module.

As to Regex... I precompile it.
Comment permalink 3 David Rhodes |
Milan, do you have the code to add to the HTTPModule to rewrite the action attribute correctly. I had the same problem removing the action attr. totally, it also stops asp.net client-side validation.
Comment permalink 4 Milan Negovan |
The XHTML filter code should have a regex to deal with it.
Comment permalink 5 Ezequiel Espíndola |
Milan, I was reading your post and though about a combination I should try as I don't know if it would work. According to Scott Allen on his post
The Passion and the Fury of URL Rewriting the solution to the action problem is much simpler, just use RewritePath again. This is the solution used on the Community Starter Kit also.
Do you think this method would work by binding to another event from the HttpModule or using a filter like you do? I believe it should execute RewritePath just before the destination page gets processed. Is there such a way to do it?
Comment permalink 6 Milan Negovan |
Ezequiel, is sounds feasible. I'm not sure which event I'd wire it to, though. It could be done from a filter.

Emails and Notifications

Would you like to be notified when somebody responds to this post?  Would you like to have these comments emailed to you?

TrackBacks

Sorry, TrackBacks are not allowed.

Submit your comment

Please enter only text since all HTML tags except hyperlinks will be stripped. Hyperlinks will become live links. Any comments with flaming or offensive language will be deleted. Be courteous to other posters. Thank you.

Your name (required):
Your email (optional):
Your site's URL (optional):
Enter this number
Type in the number above:
Comment (required):