Skip Navigation LinksHome > View Post

Validator Module

Bruusi and I have been passionate about the use of XHTML for a while now (read bruusi's post about why he loves XHTML).

But getting it right is hard. Let me explain why...

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.

The validator in action

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?

First, did you try the demo? If not, go and try it now.

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'.

<configSections>
<section name="validatorModule"
type="Tjoc.Web.Validator.ValidatorConfigHandler, Tjoc.Web.Validator"/>
</configSections>

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.

<validatorModule enabled="true" mode="Comments"
customRenderer="MyNamespace.MyCustomRenderer, MyAssembly">

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.

<proxy server="proxyserver" port="80" domain="domainname"
username="username"
password="password"/>

A list of page extensions for which you want the validator to run, probably just '.aspx'.

<pageExtensions>
<add value=".aspx"/>
</pageExtensions>

A list of content types for which you want the validator to run, probably just 'text/html'.

<contentTypes>
<add value="text/html"/>
</contentTypes>
</validatorModule>

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>
<add type="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.

Download

You can download the validator module here (9.93KB).

Download

UPDATE: Read Josh's post about how to Extend the Validator Module.

UPDATE: The Source Code is now available for download.

UPDATE: Use the XHTML Validator with any source of HTML: find out more.

Tags: ASP.NET

 
Josh Post By Josh Twist
12:08 AM
21 Feb 2006

» Next Post: Problem with designer in VS Team Suite RTM
« Previous Post: Now with added comments

Comments are closed for this post.

Posted by Dirk Rombauts @ 31 Mar 2006 12:25 AM
This is cool! Is there a way to configure the validator to check for xhtml 1.0 strict?

Posted by Josh Twist @ 31 Mar 2006 12:39 AM
Hi Dirk,

No problem. The validator will read the DOCTYPE from your source and validate whatever version of XHTML you are using, even if it's different on every page.

Glad you like it.

Josh

Posted by Martin Brown @ 31 Mar 2006 12:42 AM
That’s a great idea! I'm installing this on my QA machines ASAP.

I would be interested in a .Net 1.x version but it would also have to support HTML 4.01 validation.

Just a suggestion for a future version, but I think it would be good to see the result at the bottom of the page in a similar way to ASP.Net tracing?

Anyway, great work.

Posted by Josh @ 31 Mar 2006 12:46 AM
Hi Martin,

If you want the report at the bottom of the page you can just set the mode to Html:

<validatorModule enabled="true" mode="Html"> ...

Josh

Posted by Scott Hanselman @ 31 Mar 2006 1:25 AM
Mode=html isn't really intuitive if it means "include the html and put us at the bottom" IMHO...

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:

<configuration>
<system.web>
<!--
<xhtmlConformance mode="Transitional" [Transitional | Legacy | Strict] />
-->
<xhtmlConformance mode="Strict" />
</system.web>
</configuration>

This removes the name attribute in viewstate for example.

NB: This is new to ASP.NET 2.0

Posted by Bernhard Hofmann @ 10 Apr 2006 4:55 AM
Fantastic work. I'm going to add this to my website and start the long but worthwhile process of making it XHTML and WAI-AAA compliant.

My sincere gratitude and deep respect. Awsome work!

Posted by Dan @ 10 Apr 2006 11:40 AM

Any chance of being able to use a proxy without storing the username/password in the web.config?

Perhaps use whatever proxy information is already stored in Control Panel -> Internet Options

Otherwise great job! This is going to be one of those tools I wonder how I ever lived without.

Posted by Josh @ 10 Apr 2006 1:08 PM
Thanks Bernhard & Dan,

Maybe automatic proxy config using Internet Connection settings is something I can look into for the next release, though I can't see any obvious way around the password issue.

The way I circumvented this was to ask our proxy guys to allow unauthorised access to just the W3C site. Most proxies support this kind of setup.

Thanks again. PS - be sure to checkout the latest post on how to extend the module.

Posted by Simon @ 28 Apr 2006 7:00 AM
Hi!

What if I have javascript code inside the website?
for (var i=0;i<10;i++)
{
document.writeln (i);
}

It doesn't work:
Error: Name cannot begin with the '1' character, hexadecimal value 0x31. Line 16, position 16. (Line:16, Position:16)

Regards
Simon

Posted by Simon @ 28 Apr 2006 7:18 AM
Hi!

I found the correct solution!
// <![CDATA[
for (var i = 0; i< 10; i++)
document.writeln(i);
// ]]>

Thanks!

Regards
Simon

Posted by Guest @ 24 May 2006 11:46 AM
really cool, thanks!

looking for the same validation for rss/atom, anyone know?

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.

Posted by Josh @ 02 Jun 2006 1:30 PM
Hi Rick,

Glad you like the module. I wrote a post a couple of months back about how you could easily extend the module to send e-mails at this url: http://www.thejoyofcode.com/Extending_the_Validator_Module.aspx

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?

Josh

Posted by Simon @ 27 Jul 2006 3:19 AM
Hi Josh, thanks for the quick answer.
Atlas produces following Code:
<script type="text/xml-script">
<page xmlns:script="http://schemas.microsoft.com/xml-script/2005">;
<components>
<pageRequestManager id="_PageRequestManager" updatePanelIDs="ctl00$GamesHead$balanceUpdatePanel" asyncPostbackControlIDs="ctl00_GamesHead_lnkRefreshBalances" scriptManagerID="ctl00$GamesHead$headScriptManager" form="aspnetForm" />
</components>
</page></script>
<script type="text/javascript">
</script>

xhtml error report:
XHTML Report (Validation took: 15,625ms)

Error: The element 'script' cannot contain child element 'page' because the parent element's content model is text only. (Line:94, Position:2)
Error: The 'page' element is not declared. (Line:94, Position:2)
Error: The 'components' element is not declared. (Line:95, Position:4)
Error: The 'pageRequestManager' element is not declared. (Line:96, Position:6)

The problem is, that if it always failes, nobody will look at that!

Link to "Atlas and Xhtml compliant"
http://forums.asp.net/thread/1236258.aspx

Regards
Simon

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.

Posted by Josh @ 16 Nov 2007 1:56 PM
Hi Debasish,

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....

Posted by Josh @ 14 Jan 2008 9:45 AM
>> does java provide better classes then .NET

Well, maybe, but in this case the w3c guys have just taken a totally different approach which I don't have time to replicate :(

Posted by Debasish Pramanik @ 23 Jan 2008 7:47 PM
My latest post does exactly answer the question
http://debasishpramanik.wordpress.com/2008/01/14/url-xhtml-validator-tool/

Have a look at it let me know.

Posted by Luka @ 04 Aug 2008 5:26 AM
I tried it, but i'm getting system exception error. Spend all day trying to figure out and no luck.

Posted by Josh @ 04 Aug 2008 1:06 PM
Can you share the exact details of the exception?

Posted by Mark @ 29 Apr 2009 6:35 PM
Its great!

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.

Posted by alan @ 30 Oct 2009 1:44 PM
Hi Josh,
i'm trying to run your validator w/ NAAK and am getting this error. searched all over the web for solution but i'm stumped!
the error:
Error: Parameter entity 'HTMLlat1' references itself. Line 29, position 2. (Line:29, Position:2)

here's what the top of my page looks like:
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">;
<html xmlns="http://www.w3.org/1999/xhtml"; xml:lang="en" lang="en">

<head id="ctl00_ctl00_SiteMasterHead"><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /><title>

Can you help??
thanks,alan

Posted by alan @ 30 Oct 2009 1:57 PM
took out the naak stuff and just ran the validator
same error:
XHTML Report (Validation took: 0ms)

* Error: Parameter entity 'HTMLlat1' references itself. Line 29, position 2. (Line:29, Position:2)

Posted by Chris W. @ 08 Mar 2011 6:04 PM
Alan,

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.

(See http://msdn.microsoft.com/en-us/library/system.xml.xmltextreader.dtdprocessing.aspx.)

© 2005 - 2014 Josh Twist - All Rights Reserved.