Take this site. We set out with a solid aim to make our site fully XHTML compliant and went about it in the usual way. That is, you write a page, you render it and you cut and paste the source into a HTML validator.

That sounds easy enough (if a little boring) but the thing you have to remember is that this very simple blog is dynamic. Not very dynamic, admittedly, but it is dynamic.

Take the comments link at the bottom of each post. It's a complicated little beast. If comments are disabled then it doesn't appear at all. If an editor is logged in then it appears underneath an 'Edit Post' link. If you're viewing the individual post it's replaced by the comments themselves. To be sure your site is fully XHTML compliant you have to test all these scenarios, and trust me - it'll be these little puppies that catch you out.

I once tried to solve this problem and coded a spider that crawled a web site and validated every page, generating a report at the end (we actually used the spider during the development of this site). But there was one key thing missing, the spider couldn't log in. It couldn't interact with the site and Post a comment. It could only follow the links.

So, what's the solution?

Step up theJoyOfCode.com's Validator Module. The idea is simple. Configure your website to use our Validator Module and every time a page is rendered you'll get a little report at the top or bottom of your page (your choice). Actually, you'll get a big red report if anything is wrong.

We've put together a simple demonstration area where you can see the module in action. Why not try it quickly before reading on?

How do you use it?

Ahem. How do you use it? Right. Easy peasy. Drop the assembly into the bin folder of your ASP.NET 2.0 web application. Add a couple of entries (details below) to your web.config and you're away! We recommend enabling the full validation report for development and possibly QA and disabling it entirely on live. Though you could enable comments mode on live, it's entirely up to you!

How does it work?

The module watches ASP.NET render your HTML and just before it sends it back to your browser, the module validates the output. The validator actually goes off to the W3C's website to fetch the latest relevant DTD files (yes, it does require internet connectivity, don't worry though - proxy support is included and the files are cached so they are only accessed once per appdomain). Finally, a report is appended to your output either as HTML comments or glorious full-color HTML.

How do you set it up?

Lets look at the pieces of configuration you'll need to add to your web.config to use the Validator Module.

First we need to instruct ASP.NET to expect our custom configuration section 'validatorModule'.

Next, we setup how we want the validator to work. The enabled attribute turns the validator on and off (true or false). The mode attribute determines how the validation report is rendered (one of Html, HtmlFloat, Comments or Custom). The customRenderer attribute specifies a custom implementation of IValidationRenderer.

The optional proxy element configures a proxy server and its attributes should be fairly self explanatory. However, if you don't need to authenticate with your proxy the domain, username and password values don't need to be specified.

The following section is required inside the system.web section to add the module to the ASP.NET pipeline.

<!-- note this is inside the system.web node --><httpModules><addtype="Tjoc.Web.Validator.ValidatorModule, Tjoc.Web.Validator"name="ValidatorModule"/></httpModules>

I realise how difficult it is to cut and paste from this page so there is an example config provided in the download (below).

Requirements

Fortunately, this is a pretty short list. Your app needs to be running under ASP.NET 2.0* and it needs access to the internet. Given you're most likely to be using the validator on your development workstation I can't imagine the latter being a problem. And that's about it.

*The module could be fairly easily back ported to work for .NET 1.x but I'm lazy. If there's enough demand I'll make a 1.x version too. The only reason the source code isn't included is to keep the download size small, if you want the original source code just drop me a line.

Posted by
Josh
@
31 Mar 2006
1:44 AM
I can see your point Scott, it's one of those evolutionary things. We started only with Comments and Html modes (where the output is always at the bottom) and then I thought it might be useful to have one that floats at the top and gets right in your face. I didn't want to change the name at that point because some people were already using the Html mode.

I'll leave it as is for now and consider changing the name in the next release (with support for Html to keep things backwards compatible).

Thanks everybody for your feedback! Keep it coming.

Josh

Posted by
Bruusi
@
03 Apr 2006
12:52 AM
To those of you who want to check for XHTML strict, remember to set the xHtmlConformance mode to "Strict" in the web.config file:

Posted by
Rick
@
02 Jun 2006
1:13 PM
Josh, this is great. I had no inkling how I might get other team members working with XHTML, but this could do it.

I'd like to see an option to have it email the warning to a specific address. I wouldn't have it running on a public site, but it could usefully run in a semi-live environment used only by staff. I wouldn't want them to see the warnings, but I'd want to know about them. I'd want to know details of the request too, so that I can recreate it - so include an interation through the Request.Form, QueryString and ServerVariables collections. Of course, the destination email address and the SMTP server would need to be config settings.

I'd also be interested in a 1.1 version. We're keen to upgrade to 2.0 but with a big site with lots of interdependent projects, it's difficult to find a time to set-aside for the changeover. For now all I can do is bookmark it.

I haven't had many requests for a 1.1 version (just 3 including yours) so I'm afraid I've not started work on it. Sadly, I have too many other commitments to promise anything at the moment. However, a reasonable C# coder should be able to back-port it without too much difficulty.

Furthermore, I'm pretty sure you can run a 1.1 site under .NET 2.0 without any problems - just change the version on the ASP.NET tab in IIS. I believe this kind of backward compatibility was one of the goals of ASP.NET 2.0.

Josh

Posted by
Rick
@
04 Jun 2006
10:40 AM
Thanks Josh. The site in question is running on IIS5 so I don't think we can switch to v2 in the way you suggest, but we're definitely planning to make the switch as soon as we can.

Posted by
Jørn Schou-Rode
@
08 Jun 2006
11:51 AM
Thanks! I really appriciate the option of using a "custom renderer", which make this solution truly object oriented :) Running quite a lot of web apps with user generated content, a centralized database driven web service seems to be my choice of "rendering".

Posted by
Josh
@
09 Jun 2006
6:40 AM
That's Great Jørn! I love to hear about how people are using this thing.

PS - Rick (above), don't want to go too off topic but I'm pretty sure IIS5 supports asp.net 2.0 in the way I described, but you won't get the option unless you install that runtime (obviously)

Posted by
Simon
@
26 Jul 2006
6:20 AM
Hi!Is there a way to define special cases?Atlas for example, render at the moment invalid xhtml!

regards Simon

Posted by
Josh
@
26 Jul 2006
11:19 AM
Sorry Simon, there currently isn't anyway of excluding 'special cases'. I'm not sure I think this would be a good idea either, I'd just advise you to keep your error count as low as possible.

Do you have any info as to what part of Atlas is causing your problems?

Posted by
Unknown
@
10 Dec 2006
6:20 PM
How can I validate the code in asp.net 1.1? Is there something like this one?

Posted by
Josh
@
11 Feb 2007
12:16 AM
Sadly there isn't a version of the Validator specifically for 1.1 though you could download the source and adjust the code yourself. Also, you could use Vista for development and use the integrated pipeline instead: http://www.thejoyofcode.com/XHTML_Validator_For_All.aspx

Posted by
Jan Andersen
@
06 Jun 2007
12:38 AM
Is there an option to have the source af the line in eroror listed?

Regards

Jan Andersen

Posted by
Jan Andersen
@
06 Jun 2007
4:10 AM
The validator is working, but I get several messages about schema:

Could not find schema information for the element 'validatorModule'.

Posted by
Debasish Pramanik
@
15 Nov 2007
6:14 AM
Hi:First of all thanks for the great stuff. But I'm facing some huge issue. The errors displayed are not same as displayed by http://validator.w3.org. There is a huge difference. Can you please let me, also sometime it shows wrong number of errors even though there are moe errors. For e.g <div> <p> <//p>

<br/> </div> <div> <table>

The above should give 3 errors but it gives only one error. Please help !!!!!

Posted by
debasishpramanik
@
15 Nov 2007
6:15 AM
Please put the code within Form tag of the aspx page.

The module uses .NET's XmlValidatingReader with the DTD provided by the W3C to perform the validation.

Sadly, this only works against valid XML documents and since your HTML is invalid XML it doesn't make it to the DTD validation and therefore you don't get the full list of errors - only the ones that describe the invalidity of the markup.

With regard to putting the output into the form tag, I did look at this but since the Validator Module was only designed for design-time work then I didn't put the extra effort in to make this happen.

However, the source is provided so you should be able to implement this yourself without too much difficulty.

Posted by
Debasish Pramanik
@
18 Nov 2007
7:54 AM
Thanks for the reply. I hope you have seen my post related to the module. I hope you liked it.

Regarding the error, this is really sad. My question is then how validator.w3.org guys are doin...does java provide better classes then .NET....

Would be good to allow me to override the CSS that is applied to the html div in the config. That way I don't have to go making my own render (Figuring out where and how to maintain it etc), if I just want to display the message differently..

Posted by
dusty
@
26 Aug 2009
2:59 PM
Great addition to my site... i have a problem though.. i am using Routing, so all my pages look like: http://www.mydomain.com/user/register. how can i validate them i tried setting the page extensions and content types but with no luck.

A co-worker and I have been puzzling over the same error, which we encountered when he re-targeted a .NET 3.5 project to .NET 4.0 in VS 2010. The app uses an XmlTextWriter to read an XHTML document with the same standard W3C DOCTYPE -- XHTML Transitional -- except that the SYSTEM part of the DOCTYPE points to a local (downloaded) copy of the DTD.

We're stumped; it sure looks like a bug in .NET 4.0. He bailed and went back to .NET 3.5.

NOTE: Along the way, we dealt with .NET 4.0's deprecation of the boolean ProhibitDtd property of the XmlTextReader and XmlReaderSettings classes, in favor of the new DtdProcessing property with an enum value (flags enum). When we use the new property's 'Parse' value, we get the same error you reported.