Server-side AJAX Validator
I have talked before about server-side validation using the ASP.NET validation framework. A typical scenario would be, for example, to validate the existance of a given username, in a registration form. This time, I present here a much simpler way, which is self contained and doesn't even require a ScriptManager.
Basically, it is a class that extends CustomValidator and adds a JavaScript AJAX (or, should I say, SJAX, since it is synchronous) call to the server. If an event handler for the ServerValidate event exists, it is given the chance to invalidate the validator. No client-side validation is performed (the ClientValidationFunction is ignored).
First, the code:
public class ServerValidator : CustomValidator, IPostBackEventHandler { protected override void OnPreRender(EventArgs e) { if ((this.Visible == true) && (this.Enabled == true)) { String script = "\nfunction ValidateServerValidator(sender, args)\n" + "{\n" + " var xhr = null;\n" + " if (window.XMLHttpRequest)\n" + " {\n" + " xhr = new XMLHttpRequest();\n" + " }\n" + " else\n" + " {\n" + " xhr = new ActiveXObject('Microsoft.XMLHTTP');\n" + " }\n" + " xhr.open('POST', document.location.href, false);\n" + " xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');\n" + " xhr.setRequestHeader('x-microsoftajax', 'Delta=true');\n" + " xhr.setRequestHeader('x-requested-with', 'XMLHttpRequest');\n" + " xhr.send('__ASYNCPOST=true&__EVENTARGUMENT=' + escape(args.Value) + '&__EVENTTARGET=' + sender.id.replace('_', '%24'));\n" + " var array = xhr.responseText.split('|');\n" + " args.IsValid = (array[0] == 'true');\n" + "}\n"; this.ClientValidationFunction = "ValidateServerValidator"; this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "ValidateServerValidator", script, true); } base.OnPreRender(e); } protected override void OnInit(EventArgs e) { if ((this.Visible == true) && (this.Enabled == true)) { this.Page.RegisterRequiresRaiseEvent(this); } base.OnInit(e); } #region IPostBackEventHandler Members void IPostBackEventHandler.RaisePostBackEvent(String eventArgument) { this.Context.Response.Clear(); this.Context.Response.Write(String.Concat(this.OnServerValidate(this.Context.Request.Form [ "__EVENTARGUMENT" ]).ToString().ToLower(), "|")); } #endregion }
Now an example declaration on an ASPX page:
<asp:TextBox runat="server" ID="username"/> <web:ServerValidator runat="server" ControlToValidate="username" ErrorMessage="Username already taken" OnServerValidate="CheckUsername"/> <asp:Button runat="server" Text="Check Valid Username" />
Hope you enjoy it!