Extending the Validator Module
ScottGu kindly called out our
Validator Module on Sunday and it's getting more and more popular. So now seems like a good time to talk about how it can be extended.
There are three rendering modes built-in to the Validator Module:
Html (displays a report at the bottom of the page)
<validatorModule mode="Html" ... >
HtmlFloat (displays a floating report at the top of the page)
<validatorModule mode="HtmlFloat" ... >
Comments (writes comments at the bottom of your HTML source)
<validatorModule mode="Comments" ... >
Additionally, there is a fourth setting:
Custom (up to you :)
<validatorModule mode="Custom" customRenderer="YourNamespace.YourClass, YourAssembly" ... >
This setting allows you to specify your own class to render the report. To explain how this works, I'll walk through a quick example.
To demonstrate how to implement your own renderer we'll create a quick and simple SmtpRenderer class that sends an e-mail whenever an invalid document is rendered.
First we create a new class library project (in .NET 2.0) and we'll need to add a reference to the Validator Module assembly itself (download it
here).
Next we add our class and implement the IValidationRenderer interface (in the Tjoc.Web.Validator namespace).
using System;
using System.Collections.ObjectModel;
using System.Web;
using System.Text;
using System.Net.Mail;
using System.Configuration;
using Tjoc.Web.Validator;
namespace MyValidatorExtension
{
public class SmtpRenderer : IValidationRenderer
{
}
}
The IValidationRenderer interface has one method, Render, which is passed the current HttpResponse object, a Collection of ValidationRecords and the time it took to validate the response. The code here is very simplistic and for demonstration purposes; the comments should explain what's going on:
public void Render(
HttpResponse response,
Collection<ValidationRecord> errors,
TimeSpan validationDuration)
{
// Guard clause to see if validation failed
if (errors.Count == 0)
{
return;
}
// Use a string builder to create the message body
StringBuilder body = new StringBuilder();
// Note the page in which the error occured...
body.Append("XHTML Validation Error in page ");
body.AppendLine(HttpContext.Current.Request.RawUrl);
body.AppendLine();
// ... and the details of each error
foreach (ValidationRecord error in errors)
{
body.AppendLine(error.ToString());
body.AppendLine();
}
// Finally, note how long validation took
body.AppendFormat("Validation took {0}", validationDuration);
// Create the message and read the addressee from appSettings
MailMessage message = new MailMessage(
"Validator Module <validator@example.com>",
ConfigurationManager.AppSettings["validatorMailAddress"]);
message.Subject = "Validator Report";
message.Body = body.ToString();
SmtpClient client = new SmtpClient();
// Send the mail!
client.Send(message);
}
Finally, We need to add the target mail address to web.config, setup the SMTP Host and specify our custom renderer
<validatorModule enabled="true" mode="Custom" customRenderer="MyValidatorExtension.SmtpRenderer, MyAssembly">
...
<appSettings>
<add key="validatorMailAddress" value="josh@thejoyofcode.com"/>
</appSettings>
<system.net>
<mailSettings>
<smtp>
<network host="smtp.yourhosthere.co.uk"/>
</smtp>
</mailSettings>
</system.net>
And Bingo! An SMTP renderer for the Validation Module that sends e-mails like the one below:

It only took me twenty minutes to write this new renderer and this post.
If I was to write this for real I'd want to make sure that I wasn't inundated with mails so I'd probably make sure I was only sent an e-mail once every n minutes per page, which should be easy enough. Maybe somebody out there wants to put such an example together? If you do, let me know and I'll post a link.

Post By
Josh Twist
12:56
10 Apr 2006
» Next Post:
Truncating the transaction log
« Previous Post:
More fun with Thread Pools
Comments:
Posted by
Bernhard Hofmann
@
10 Apr 2006
23:39
Any news on a version for Framework 1.1?
Posted by
Josh
@
11 Apr 2006
01:35
I've just started a new job yesterday so things are a little hectic at the moment. It will be a month or so before I could look at a back-port.
Some people who've e-mailed me to ask for the source have indicated they want to back port themselves, hopefully they'll be willing to share their work if they're successful.
Keep watching and I'll keep you posted.
Posted by
Ashok
@
14 Aug 2007
11:23
How tough would it be to extend the Validator to display the source of the page in the floating div and to make the div collapsible via JS?
Posted by
Josh
@
14 Aug 2007
12:34
It wouldn't be easy to do it using the Extension points we built in but you have the source, it would be pretty easy to change the module to support that.