Creating a Custom Validation Control in ASP.NET

Posted by: Suprotim Agarwal , on 9/5/2008, in Category ASP.NET
Views: 212931
Abstract: The BaseValidator class defines the basic implementation needed for all Validation controls. There are 6 Validation Controls included in the ASP.NET 2.0 and ASP.NET 3.5 framework, however with a few shortcomings. In this article, we will explore how to create a custom validation control in ASP.NET and provide both Server and Client Side Validation for the same.
Creating a Custom Validation Control in ASP.NET
 
The BaseValidator class defines the basic implementation needed for all Validation controls. There are 6 Validation Controls included in the ASP.NET 2.0 and ASP.NET 3.5 framework which validate controls to prevent the users from entering wrong data. However, there are a few shortcomings in these controls. The good part is that ASP.NET provides the framework to create new validation controls. If you would like to create your own validation control, you can do so by deriving a new control from the BaseValidator abstract class. In this article, we will explore how to create a custom validation control in ASP.NET and provide both Server and Client Side Validation for the same.
Step 1: Create an ASP.NET Website (File > New > Website). Drag and drop a CheckBoxList, RadioButtonList and a Button control on to the page.
Step 2: Let us first complete the task of populating the CheckBoxList and RadioButtonList  controls in the Page_Load event as shown below:
C#
protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        List<string> lstStr = new List<string>();
        lstStr.Add("Item 1");
        lstStr.Add("Item 2");
        lstStr.Add("Item 3");
        lstStr.Add("Item 4");
        CheckBoxList1.DataSource = lstStr;
        CheckBoxList1.DataBind();
        RadioButtonList1.DataSource = lstStr;
        RadioButtonList1.DataBind();           
    }
}
VB.NET
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If (Not Page.IsPostBack) Then
            Dim lstStr As List(Of String) = New List(Of String)()
            lstStr.Add("Item 1")
            lstStr.Add("Item 2")
            lstStr.Add("Item 3")
            lstStr.Add("Item 4")
            CheckBoxList1.DataSource = lstStr
            CheckBoxList1.DataBind()
            RadioButtonList1.DataSource = lstStr
            RadioButtonList1.DataBind()
        End If
    End Sub
Step 3: Our next step would be to create the custom validation control. But before that, let us quickly take an overview of what we are trying to achieve. This sample will demonstrate that the user should select at least one checkbox and one radiobutton before submitting the form to the server. For this purpose, we will first show how to create a custom validation control to perform server-side validation and then extend the control to support client-side validation too.
Note: If you are wondering why we have chosen to create a custom validation control instead of using a CustomValidator, then I would state that the main reason for doing so is ‘reusability’. You would soon see that we will be using the same custom validation control to validate both the CheckBoxList as well as RadioButtonList. It is as simple as registering the assembly and start using it.
Step 4: To create our custom validation control, Right click the project > Add New Item > From the Template, choose ‘Class’ > Rename the class to ‘ListValidator’ or anything you like > Choose the Language (C# or VB) > Click on Add.
Note: Visual Studio would prompt you to add the class to the App_Code. Choose yes to do so.
Step 5: As already discussed, we will be deriving from the BaseValidator abstract class. You will need to implement the ‘EvaluateIsValid’ method which returns a Boolean value indicating if the field/control being validated is valid or not. The code for the server side validation will be similar to the following:
Server-Side Validation
C#
namespace CustomListValidator
{
///<summary>
/// Summary description for ListValidator
///</summary>
public class ListValidator : BaseValidator
{
    public ListValidator()
    {
 
    }
 
    protected override bool ControlPropertiesValid()
    {
        Control ctrl = FindControl(ControlToValidate) as ListControl;
        return (ctrl != null);
    }
 
    protected override bool EvaluateIsValid()
    {
        return this.CheckIfItemIsChecked();
    }
 
    protected bool CheckIfItemIsChecked()
    {
        ListControl listItemValidate = ((ListControl)this.FindControl(this.ControlToValidate));
        foreach (ListItem listItem in listItemValidate.Items)
        {
            if (listItem.Selected == true)
                return true;
        }
        return false;
    }
 
}
}
VB.NET
Namespace CustomListValidator
    ''' <summary>
    ''' Summary description for ListValidator
    ''' </summary>
    Public Class ListValidator
        Inherits BaseValidator
        Public Sub New()
 
        End Sub
 
        Protected Overrides Function ControlPropertiesValid() As Boolean
            Dim ctrl As Control = TryCast(FindControl(ControlToValidate), ListControl)
            Return (Not ctrl Is Nothing)
        End Function
 
        Protected Overrides Function EvaluateIsValid() As Boolean
            Return Me.CheckIfItemIsChecked()
        End Function
 
        Protected Function CheckIfItemIsChecked() As Boolean
            Dim listItemValidate As ListControl = (CType(Me.FindControl(Me.ControlToValidate), ListControl))
            For Each listItem As ListItem In listItemValidate.Items
                If listItem.Selected = True Then
                    Return True
                End If
            Next listItem
            Return False
        End Function
    End Class
End Namespace
In the code snippet shown above, we override the EvaluateIsValid() method. The ‘ControlToValidate’ is cast to a ListControl, which is an abstract base class for all list-type controls. We then loop through all the ListItems and if one of the items in both the CheckBoxList as well as RadioButtonList is checked by the user, we return true, else we return false.
In order to use this custom validation control on the CheckBoxList and RadioButtonList kept in our page, we will use the <%@ Register %> directive as shown below:
<%@ Register TagPrefix="CLV" Namespace="CustomListValidator" %>
<div>
<asp:CheckBoxList ID="CheckBoxList1" runat="server">
</asp:CheckBoxList></div>
        <CLV:ListValidator runat="server" ID="custLstVal" ControlToValidate="CheckBoxList1" ErrorMessage="At least one item in the checkboxlist should be checked" />
 
<asp:RadioButtonList ID="RadioButtonList1" runat="server">
</asp:RadioButtonList>
        <CLV:ListValidator runat="server" ID="custRadVal" ControlToValidate="RadioButtonList1" ErrorMessage="At least one item in the radiobuttonlist should be checked" />
<br />
<br />
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" />
As you will observe, the two controls are being validated by the same custom validation control that we are building. Run the application and click on the button without checking any items in the two controls. Two error messages are displayed when the form is submitted.
Step 6: We saw how to perform server side validation. Let us see how we can now perform validation directly on the client side, without a postback. To perform client side validation, you would need to override OnPreRender and create the javascript function using a StringBuilder object and output it using Page.ClientScript.RegisterClientScriptBlock().
Client-Side Validation
The code with the OnPreRender and JavaScript function will look similar to the following. This code is to be added in the same class where the server-side validation code was added.
C#
protected override void OnPreRender(EventArgs e)
{
    // Determines whether the validation control can be rendered
    // for a newer ("uplevel") browser.
    // check if client-side validation is enabled.
    if (this.DetermineRenderUplevel() && this.EnableClientScript)
    {
        Page.ClientScript.RegisterExpandoAttribute(this.ClientID, "evaluationfunction", "CheckIfListChecked");
        this.CreateJavaScript();
    }
    base.OnPreRender(e);
}
 
protected void CreateJavaScript()
{
    StringBuilder sb = new StringBuilder();
    sb.Append(@"<script type=""text/javascript"">function CheckIfListChecked(ctrl){");
    sb.Append(@"var chkBoxList = document.getElementById(document.getElementById(ctrl.id).controltovalidate);");
    sb.Append(@"var chkBoxCount= chkBoxList.getElementsByTagName(""input"");");
    sb.Append(@"for(var i=0;i<chkBoxCount.length;i++){");
    sb.Append(@"if(chkBoxCount.item(i).checked){");
    sb.Append(@"return true; }");
    sb.Append(@"}return false; ");
    sb.Append(@"}</script>");
    Page.ClientScript.RegisterClientScriptBlock(GetType(),"JSScript", sb.ToString());
}
VB.NET
        Protected Overrides Sub OnPreRender(ByVal e As EventArgs)
            ' Determines whether the validation control can be rendered
            ' for a newer ("uplevel") browser.
            ' check if client-side validation is enabled.
            If Me.DetermineRenderUplevel() AndAlso Me.EnableClientScript Then
                Page.ClientScript.RegisterExpandoAttribute(Me.ClientID, "evaluationfunction", "CheckIfListChecked")
                Me.CreateJavaScript()
            End If
            MyBase.OnPreRender(e)
        End Sub
 
        Protected Sub CreateJavaScript()
            Dim sb As StringBuilder = New StringBuilder()
            sb.Append("<script type=""text/javascript"">function CheckIfListChecked(ctrl){")
            sb.Append("var chkBoxList = document.getElementById(document.getElementById(ctrl.id).controltovalidate);")
            sb.Append("var chkBoxCount= chkBoxList.getElementsByTagName(""input"");")
            sb.Append("for(var i=0;i<chkBoxCount.length;i++){")
            sb.Append("if(chkBoxCount.item(i).checked){")
            sb.Append("return true; }")
            sb.Append("}return false; ")
            sb.Append("}</script>")
            Page.ClientScript.RegisterClientScriptBlock(Me.GetType(), "JSScript", sb.ToString())
        End Sub
As you observe, we override the OnPreRender method and use the RegisterExpandoAttribute to assign the function name ‘CheckIfListChecked’ an attribute called ‘evaluationfunction’. The javascript function(CheckIfListChecked) takes one parameter, the validator object and returns ‘true’ if Valid (item in both Radiobuttonlist or CheckBoxList is checked) and ‘false’ if Invalid (Item in either Radiobuttonlist or CheckBoxList is not selected).
Note: If you observe, there is a call to the base.OnPreRender() in the OnPreRender method. This is done to make sure that if the users have turned off javascript on their browsers, then this call passes the control back to the page and allows the rendering to continue by calling base.OnPreRender() .
The javascript function is created using a StringBuilder object and is output using Page.ClientScript.RegisterClientScriptBlock()
When the page is run, the javascript output to the browser will look similar to the following:
<script type="text/javascript">
function CheckIfListChecked(ctrl)
{
var chkBoxList = document.getElementById(document.getElementById(ctrl.id).controltovalidate);
var chkBoxCount= chkBoxList.getElementsByTagName("input");
for(var i=0;i<chkBoxCount.length;i++)
{
if(chkBoxCount.item(i).checked)
{
return true;
}
}return false;
}
</script>
Step 7: The last step would be to add the EnableClientScript="true" to our custom validation controls as shown below:
        <CLV:ListValidator runat="server" ID="custLstVal" EnableClientScript="true" ControlToValidate="CheckBoxList1" ErrorMessage="At least one item in the checkboxlist should be checked" />
 
        <CLV:ListValidator runat="server" ID="custRadVal" EnableClientScript="true" ControlToValidate="RadioButtonList1" ErrorMessage="At least one item in the radiobuttonlist should be checked" />
 
That’s pretty much it. This time when you run the application, the custom validation control handles both server-side as well as client-side validation. If JavaScript is enabled on your browsers, the validation errors are displayed before the form is posted back to the server. The entire source code of the application can be downloaded from here. I hope you liked the article and I thank you for viewing it.

This article has been editorially reviewed by Suprotim Agarwal.

Absolutely Awesome Book on C# and .NET

C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.

We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).

Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.

Click here to Explore the Table of Contents or Download Sample Chapters!

What Others Are Reading!
Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+

Author
Suprotim Agarwal, MCSD, MCAD, MCDBA, MCSE, is the founder of DotNetCurry, DNC Magazine for Developers, SQLServerCurry and DevCurry. He has also authored a couple of books 51 Recipes using jQuery with ASP.NET Controls and The Absolutely Awesome jQuery CookBook.

Suprotim has received the prestigious Microsoft MVP award for Sixteen consecutive years. In a professional capacity, he is the CEO of A2Z Knowledge Visuals Pvt Ltd, a digital group that offers Digital Marketing and Branding services to businesses, both in a start-up and enterprise environment.

Get in touch with him on Twitter @suprotimagarwal or at LinkedIn



Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!
Comment posted by redsquare on Thursday, September 11, 2008 6:15 AM
Yak, all that script inside a string builder, not very maintainable. Why not create a proper control and have it serve a js file so it can be cached rather than having to emit the script into the page every time.
Comment posted by Suprotim Agarwal on Thursday, September 11, 2008 8:09 AM
redsquare: Agreed. It is a good practice to include the javascript code inside a seperate js file.
Comment posted by Thargol on Monday, September 15, 2008 8:27 AM
Page.ClientScript.RegisterClientScriptBlock has a much overlooked fourth parameter that generates the script-tags for you. Using this parameter multiple calls to RegisterClientScriptBlock get combined to a single block, saving some bytes on script-tags.
Comment posted by Suprotim Agarwal on Monday, September 15, 2008 8:37 AM
Thanks for that tip Thargol. A handy one indeed!!
Comment posted by ddd on Thursday, September 25, 2008 8:21 AM
ddd
Comment posted by Harsha on Tuesday, October 21, 2008 3:57 PM
What are the shortcomings with the built in validation controls?
Comment posted by Mark Kamoski on Wednesday, October 22, 2008 6:18 AM
Nice article. You might be able to use... if (ListControl.SelectedIndex >= 0) ...to find out if there is an item selected, instead of a loop. A minor performance boost, perhaps. Regardless, thanks for the code. -- Mark Kamoski
Comment posted by Suprotim Agarwal on Wednesday, October 22, 2008 11:46 AM
Harsha: The built in validation controls handle most of your validation needs. At times when you need to perform complex validation, these validation controls may fall short. Examples can be like the one demonstrated in this article or even for simple cases where you need to validate a user input against an even or odd number.

Mark: Thanks for that tip!
Comment posted by spikey on Wednesday, October 22, 2008 7:20 PM
Sorry I have a problem with this code please can somebody help it wud be great.

The prob is when I added the tag prefix <CLV:ListValidator in my Default.aspx page it says Unrecognized tag prefix I dont know y???
Comment posted by Suprotim Agarwal on Wednesday, October 22, 2008 10:20 PM
spikey: How have you declared the <%@ Register directive as?

<%@ Register TagPrefix="CLV" Namespace="CustomListValidator" %>
Comment posted by Pawan Kumar on Friday, October 24, 2008 8:25 AM
In my point of view the validation controls provided by the VS2005 IDE is sufficient for all type of validation, It will meet most the requirement of any type of project.
http://dev.
Comment posted by khurram baloch on Sunday, October 26, 2008 3:17 PM
same is what is happening with me .. when i added the tag prefix <CLV:ListValidator inmy default aspx page it says Unrecognized tag prefix , what is the solution for this error !
Comment posted by Suprotim Agarwal on Wednesday, October 29, 2008 12:36 AM
Khurram: How have you declared the <%@ Register directive as?

<%@ Register TagPrefix="CLV" Namespace="CustomListValidator" %>

Is the user control registered?
Comment posted by David Adams on Saturday, November 15, 2008 11:43 AM
I found that when using a custom validator in an updatepanel that immediately after you call UpdatePanel.Update() server-side that it seems to blow up the validation control.  I traced it back (after many agonizing hours) back to the RegisterExpandoAttribute(evaluationfunction,...) section.  I put this in the AddAttributesToRender event and had to add this:

writer.AddAttribute("evaluationfunction", "ValidatorIsValid"); (for IE at least).  

I'm curious as to if anyone else has come across this issue.
Comment posted by Bryan Scott on Tuesday, November 18, 2008 4:27 PM
nice....but wont work with AJAX update panel...bummer
Comment posted by Guy Silva on Thursday, January 29, 2009 1:32 PM
I'm having problems using the validation class when inside a webcontrol. It simply won't validate. I'm not sure if im doing something wrong, but when I use it on a main page, instead of a webcontrol, there are no problems and the validation works as expected. Is there any known issue using the validator on webcontrols?
Comment posted by Michel on Thursday, February 26, 2009 11:41 AM
Excellent article. Thanks
Comment posted by Frank on Monday, May 25, 2009 12:41 PM
I followed the instructions and created a custome validator for a checkbox which works perfect the only prblem that i have is that i can not add this custome validator to the validation summary of the page? my guess is there should be another step! please let me know if there is a solution for this.

Thank you and thanks again for the post it is very practical.
Comment posted by Suprotim Agarwal on Friday, May 29, 2009 1:15 PM
Frank: Check Peter's answer over here: http://forums.asp.net/t/875239.aspx
Comment posted by Raj on Sunday, August 2, 2009 12:52 AM
visit <a href="http://www.codedefiner.com/aspnetValidationControls.aspx">http://www.codedefiner.com/aspnetValidationControls.aspx</a> to know more about validation controls in Asp.Net
Comment posted by pooja on Friday, August 7, 2009 8:54 AM
Thanks for the post.good article
Comment posted by tr on Tuesday, November 17, 2009 5:14 AM
**************
Comment posted by Jaivardhan on Wednesday, December 23, 2009 5:35 AM
This is a nice posting... i too have some points to share at http://jai-on-asp.blogspot.com/2009/12/validation-controls-in-aspnet.html
Hope it helps !
Comment posted by Selemani Hamisi Kumwambe on Tuesday, April 20, 2010 1:27 PM
no comment
Comment posted by Rintu on Tuesday, May 25, 2010 11:34 PM
hi,this code is very helpful for me and my programs
thanks
Comment posted by Custom Website Design on Tuesday, June 15, 2010 4:03 AM
Thank you for awesome instructions!
Comment posted by orange county restaurants on Friday, June 25, 2010 5:37 AM
I don't know much about programming. But, I am exited to know more about that. Can you tell me more about this information?
Comment posted by online degree on Friday, July 2, 2010 8:03 AM
I got an error in the checkbox area what should i do?
Comment posted by Detox your body on Monday, July 12, 2010 5:58 AM
This is a very good guide. I'm just starting with VB.net and this sure helps a lot.
Comment posted by Web 2 Design on Tuesday, July 27, 2010 1:55 AM
Excellent stuff....It really helped me in solving my problems....
Comment posted by enzino on Friday, July 30, 2010 10:07 AM
Great article! I created my owner validator with my custom CheckIfTextBoxIsValid.
I have a problem:if I set validator's display property = none when RegisterExpandoAttribute function looking for element generates a javascript error. Is there a way to create javascript variables of validator property server side mode?
Thanks
Comment posted by SEO Services on Sunday, August 29, 2010 2:27 AM
Harsha: built-in control knob check most of your needs verification. In times when you need to perform complex checks, these control checks may be lower. Examples can be as one shown in this article, or even for simple cases, when you need to validate user input on an even or odd number.
Comment posted by logoinn.com on Wednesday, September 1, 2010 12:55 AM

Excellent stuff....It really helped me in solving my problems....
Comment posted by Denzel on Tuesday, October 5, 2010 10:09 AM
Nice
Comment posted by sweating on Wednesday, October 6, 2010 11:09 PM
Very good post yes helpful, thanks
Comment posted by allegromedical on Tuesday, October 12, 2010 12:07 PM
Ohh, that's good. I have just started my classes of .NET, This would be a great platform for me to learn more here.
Comment posted by write papers online on Monday, November 8, 2010 5:15 AM

Good work done about the post, useful for my developing tasks! thanks
Comment posted by Adult Diapers on Sunday, November 21, 2010 10:16 AM
This is such a great tool which i like in dot net.
Comment posted by property management on Monday, November 22, 2010 1:00 PM
It's nice to  practice to include the javascript code inside a seperate js file.
Comment posted by suri on Monday, November 22, 2010 7:13 PM
excellent work. I am trying to find this kind of solution from last couple of days
Comment posted by foley catheters on Saturday, January 29, 2011 9:14 AM
That's very interesting to read about.. Great stuff.
Comment posted by Craig on Tuesday, February 22, 2011 7:36 AM
I have found that with this technique, blank values are unexpectedly validated.  Did you have the same problem?
Comment posted by www.merapakistan.com.pk on Saturday, March 5, 2011 1:07 AM
Good
Comment posted by Tejas on Thursday, March 17, 2011 4:32 PM
Hi,
Nice Article.
I'm doing same with custom Validator for textbox and Its not working. My code is the same as your but instead of using list control I'm using Textbox. As far as I know my javascript is not working and page is still postbacks. can you tell me the reason for it. I'll appreciate your help !!!

Here is my CreateJavaScript function:
protected void CreateJavaScript()
  {
StringBuilder sb = new StringBuilder();
            sb.Append("<script type=\"text/javascript\"> function ValidateTextBoxValue(ctrl) {");
            sb.Append(" var txtBox = document.getElementById(document.getElementById(ctrl.id).controltovalidate);");
            sb.Append("if(txtBox.value !=''){");
            sb.Append(" return true; }");
            sb.Append(" alert('Please provide value for Textbox'); return false; ");
            sb.Append("}</script>");
            Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "JSScript1", sb.ToString());
}

Here is OnPreRender Method:
protected override void OnPreRender(System.EventArgs e)
        {

            if (this.DetermineRenderUplevel() & this.EnableClientScript)
            {
                Page.ClientScript.RegisterExpandoAttribute(this.ClientID, "evaluationTextBoxfunction", "ValidateTextBoxValue");
                this.CreateJavaScript();
            }
            base.OnPreRender(e);
        }

Thanks


Comment posted by Custom Logo Design on Friday, March 18, 2011 8:19 AM
nice post thanks for shearing
http://www.logoian.com/
Comment posted by Zencart on Thursday, June 23, 2011 8:49 AM
Thanks, it's very informative post, preventing the users from entering wrong data is always important.
Comment posted by Zencart on Thursday, June 23, 2011 8:59 AM
And also I wanted to add that it's very useful thing for webshop!
Comment posted by glass doors on Thursday, August 11, 2011 3:09 AM
I have been looking for this kind of guide, good thing that I found your site. I am new in learning ASP.NET and this will help me a lot.
Comment posted by sims 3 cheat on Saturday, October 15, 2011 2:00 AM
Thanks for the information really appreciate it.
<a href="http://www.sims3cheat.com/">sims 3 cheat</a>
Comment posted by Ankit Singh on Friday, January 6, 2012 3:56 AM
Very informative post. It's really helpful for me and helped me lot to complete my task. Thanks for sharing with us. I had found another nice post over the internet which was also explained very well about Populate Grid Control From XML Document Easily, for more details of this post check out this link...

http://www.mindstick.com/Articles/535bd817-c3c1-46dd-be9c-f14e42c7db78/?Creating%20User%20Define%20Control%20in%20ASP%20.Net

Thanks
Comment posted by Ashok on Tuesday, January 17, 2012 5:40 AM
Hi friends,

I want to check a radio button list based on condition.
Means if a condion is true, the 1st button of the radion buttion list will be automatically checed.
if false then the 2nd button.

plz guide me to do this only in C# code.
Comment posted by logo items on Friday, February 3, 2012 1:22 AM
I am 13 today and I am just observing the lines of codes in your post. I want to be a programmer when I grow up and i must know how these things are done. Just telling you that I am interested to coding and I  love your post.
Comment posted by muruga on Thursday, August 16, 2012 6:11 AM
Hi Ashok PleaseFind the code:
  if (TextBox1.Text == "muruga")
            {
                RadioButtonList1.SelectedIndex = 0;
            }
            else
            {
                RadioButtonList1.SelectedIndex = 1;
            }
        }

based on my textbox value it ll decide which radio button to select,
if textbox is 'muruga' then 1st radio button,
if textbox is something else 2nd radio button ll be selected.
Comment posted by jhgjjgjgjhgg on Monday, August 20, 2012 10:21 PM
ff
Comment posted by Priti on Thursday, October 10, 2013 12:59 PM
Really Nice info.. Excellent

I found some good stuff as yours on the following link
http://freefeast.info/general-it-articles/dotnet4-0-general-it-articles/how-to-create-custom-validation-control-in-asp-net-4-0-make-custom-validation-control-using-visual-studio/
Comment posted by krishna on Monday, October 14, 2013 7:16 AM
nice