RadioButtons, Checkboxes etc cannot be validated using a traditional RequiredFieldValidator. If you try to assign ControlToValidate property of RequiredFieldValidator to a RadioButton ID then it will welcome you with an error message. The best workaround is to create a custom validator to validate RadioButtons. In this article we are going to implement a custom validator for RadioButtons but this can easily be changed to be used by a CheckBox control.

The Scenario:

The scenario is pretty simple. You have a RadioButton and you want to make sure that the user of the application checks that RadioButton. Of course we can always use custom JavaScript to perform the validation but we need a more mature solution.

In order to create a custom validator our class "RadioValidator" will derive from BaseValidator.

Here are few important methods:



EvaluateIsValid represents the validity of the validator.



The ControlPropertiesValid makes sure that the control specified by ControlToValidate property is a valid control.



The IsRadioButtonChecked is responsible for making sure that the RadioButton is checked. The FindControl method is being fed the ControlToValidate property which in this case is the ID of the RadioButton under validation.

The above code will work for the server side validation. But we also need to include the client side validation. Let's see how this can be done!



Inside the OnPreRender event we are injecting the JavaScript code into the page using the CreateJavaScript custom method which will be see in a moment. One important thing to notice is the use of the ClientScript.RegisterExpandoAttribute. The RegisterExpandoAttribute is used to inject a custom property from server side to the client side. In the above code "evaluationfunction" is a JavaScript function used by all validators to fire the client side validation. We are attaching a custom "isRadioButtonCheckedClientSide" JavaScript function to the evaluationfunction property.

Let's examine the CreateJavaScript method:



When you run the above code you will see the following JavaScript injected into the page.



Your client side validation will be enabled as well as your server side validation.

The problem with the above approach is the extra JavaScript injected into the page. This results in making the page size bigger hence descreasing the performance of the page. Let's see how we can move the JavaScript to JavaScript files and then to embedded WebResources.

We have added a JavaScript (JS) file "RadioButtonValidatorClientSideFile.js"  and a CSS file called "RadioButtonValidatorStyleSheet.css" to the same project.

We need to make both of these files part of the assembly. This will help us to improve the performance of the website as being a WebResource it will be downloaded and cached on the user's machine. This will also break the server control's dependency on external JavaScript or CSS files since now both of these files have become part of the assembly.

First in the AssemblyInfo.cs file we add the WebResources as shown below:



Be sure to add the Namespace of the project. Be sure to add the Namespace of the project. We have written the previous statement twice on purpose so that you don't forget to do that :).

You will also need to make your JS and CSS file as embedded resource. Simply, right click on the file and set the build action to embedded resource. This way both the files will become part of the server control's assembly.

Here is the code which is used to inject the JS file and CSS file to your page:



Now, when you run the page you will see two different files being downloaded from the server as shown in the screenshot below:



The embedded JavaScript also makes use of the CSS file to change the appearance of the validation message as shown in the screenshot below:



When making server controls this method ensures that everything required to run the server control is inside a single DLL.

Conclusion:

In this article we learned how to create a custom RadioButton validator control. We learned how we can inject a WebResource into the page so our JavaScript or CSS code is not downloaded on every request. There is another way to inject the script which uses ScriptManager.RegisterClientScriptResource() method. We will take a look at this method in the future article.

[Download Sample]