Data Validation


When users enter data in a form or a console application, the input often needs to be checked to verify it is a valid data value. This is important for the declared data type so any necessary conversion can correctly take place, as well as for any operations performed with it. For example, in the following Windows application form,

we should have no problem in converting the data in the interest rate TextBox (see circled data) to a Decimal type as follows:

Note here the direction of assignment; the String data in the TextBox is being converted to a Decimal type and assigned to the decimal variable (as indicated by the arrow). However, if we tried to do the same with the data in the TextBox below:

it should be obvious that this will not work, since the String "six" cannot be converted to a Decimal value. In fact, this would result in generating the following exception (more on exceptions later):

Note the error informing us that the "Input string was not in a correct format." While we could simply blame the user for silly input, that is not an acceptable way to handle this. The appropriate way to handle the invalid input situation is to validate the input before the type conversion is attempted. There are numerous ways to do this, for example disabling alphabetic key-presses, however, this is somewhat complicated and messy.

A much simpler and straight forward technique for validating data before attempting type conversion is the TryParse method1. Each base data type class (e.g. Integer, Double, etc.) has a TryParse method available for use. The TryParse method attempts to convert (i.e. parse) the source object, typically as a String type to the desired target data type. This method also returns a Boolean value indicating its success (or lack thereof). For String conversion to Decimal, the general format of the TryParse method is as follows:

The source data refers to the object that contains the original data in String format, in this case a TextBox. The target object is a variable object that is capable of storing the data, should it be successfully converted. Note the direction of the data conversion as indicated by the arrow, should it be successful. Note also that since this is a Decimal.TryParse method, the target data object must be of type Decimal. The conversion success is a Boolean return value that indicates if the conversion was successful. It should go without saying that if the data conversion was not successful, the converted data object is of no use2. Note how the components of the TryParse method correspond to the components of the Convert.ToDecimal statement above, the only extraneous component being the return status. Also take notice of the equal sign in the above example; you should understand at this point that this is the assignment operator.

If we take a look at exactly how the TryParse method is used, in combination with the control structures introduced previously, we can observe the following:

	If Decimal.TryParse (txtIntRate.Text, decIntRate) = True Then
	    
	       ' do calculations with the variable decIntRate
	
	Else

	       ' conversion failed, issue an error

	End If
	
It should be easily understood that if the conversion was successful (TryParse returns True), we can then perform some calculations with the converted values; if the conversion was not successful, we cannot. Pay close attention to the equal sign in the example above; what operator is this? It should be understood that this is the relational equality operator, and NOT the assignment operator, since this is used within the context of an If statement.

You should also understand at this point that the If statement above could also be written as:

	If Decimal.TryParse (txtIntRate.Text, decIntRate) Then
where the "= True" syntax not included. Again, this works due to the fact that Truth is implied, by default. In other words:
	If True Then ...
Students often do not like the second scenario when seeing this intially; not to worry, either syntax works fine.

1 The TryParse method is a new method introduced with .Net 2005.

2 By method definition, if the conversion fails, the Boolean return value will be False. However, if conversion fails, the value returned in the target data object will be zero. It is strongly recommended that this "feature" not be relied upon to measure success, since a valid value of zero may mimic failure. Therefore, always verify using the return status! See more here, look under remarks.


Diagnostic Messages

Now that we understand how to detect invalid data values, we can discuss how to report it to the user. The simplest and most straight forward way to do this is by using a MessageBox object. MessageBox objects are instantiated from the MessageBox class, using the Show method as follows:
	MessageBox.Show()
While this might show an instance of a MessageBox, you should ask "Where's the message?" The simplest and most common way of showing a message within a MessageBox is as follows:
	MessageBox.Show("Message Text"[, "Title"])
where the "Message Text" parameter is the message the will be displayed in the MessageBox. The optional "Title" parameter, when present will be displayed in the title bar of the MessageBox. Note the data type of both the message and the title are type String. All MessageBoxes should include "Message Text" or they would not be of much use. For example, the following code:
	MessageBox.Show("Bogus data...stop that!", "Bogus data")
will produce the following MessageBox:

Observe what is the message text and what text makes up the title. MessageBox objects always appear center-screen, and always have the grey color as above. The (horizontal) size of a MessageBox will be dependent upon the amount of text (and any other objects) within the box. By default, simple MessageBox objects have only an OK button. Using a MessageBox object this way is a simple technique to point out to a user that some unfortunate event has taken place, such as invalid data. It is important to understand that program execution will pause while a MessageBox appears on the screen, until any button is pressed to dismiss the MessageBox (e.g. the OK button).

You can build more elaborate MessageBox objects by including one or two optional parameters to indicate exactly which buttons the MessageBox will display, or which icons the MessageBox will include. The general format for this is:

	MessageBox.Show("Message Text"[, "Title"][, MessageBoxButtons][, MessageBoxIcons])
Should alternative buttons be desired, this can be done using the MessageBoxButtons enumeration with one of the following members:
	AbortRetryCancel
	OK
	OKCancel
	RetryCancel
	YesNo
	YesNoCancel
As mentioned, if no buttons are specified, the OK button is the single button displayed, as in the example above. Creating a MessageBox containing the Retry and Cancel buttons would be coded as follows (note the underscore on the Show line is merely a line continuation character for readability):
	MessageBox.Show("You must enter a positive value!", "Invalid Value", _
			 MessageBoxButtons.RetryCancel)
Which would produce the following MessageBox:

Obviously, the above only makes sense should the situation require a Retry and a Cancel operation.

Once a MessageBox displays more than one button, the user obviously has more than one option to select. With more than one option, we need a way to determine which button the user selected. This is done by querying the return value from the MessageBox, which returns a DialogResult enumeration type. These enumerations are the individual button names, e.g. Abort, Retry, Cancel, OK, Yes, and No. For example,

	Dim result As DialogResult
		
	result = MessageBox.Show("You must enter a positive value!", "Invalid Value", _
			 MessageBoxButtons.RetryCancel)

	' check if Cancel button was clicked
	If result = DialogResult.Cancel Then
		
Another way to query the return value from a MessageBox is by putting the MessageBox function directly into a conditional statement as follows:
	' check if Cancel button was clicked
	If MessageBox.Show("You must enter a positive value!", "Invalid Value", _
			 MessageBoxButtons.RetryCancel) = DialogResult.Cancel Then
		
This approach skips the intermediate step of assigning the result to a variable of type DialogResult. Either approach will work equally well, assuming you understand the logic surrounding it1.

As mentioned above, you can also specify an additional optional parameter to indicate exactly which icon, if any the MessageBox will display. This is done using the MessageBoxIcon enumeration with one of the following members:

	Asterisk
	Error
	Exclamation
	Hand
	Information
	None
	Question
	Stop
	Warning	
Note that if no icon is specified, the None icon is the default, as in the example above. Using the above example, adding a Warning icon is done as follows:
	Dim result As DialogResult
		
	result = MessageBox.Show("You must enter a positive value!", "Invalid Value", _
			 MessageBoxButtons.RetryCancel, MessageBoxIcon.Warning)
Which would produce the following MessageBox:

Note the above example can also be coded as follows:

	Dim strMessage As String = "You must enter a positive value!"
	Dim strTitle As String = "Invalid Value"
	Dim buttons As MessageBoxButtons = MessageBoxButtons.RetryCancel
	Dim icon As MessageBoxIcon = MessageBoxIcon.Warning
	Dim result As DialogResult
		
	result = MessageBox.Show(strMessage, strTitle, buttons, icon)
Note also that if a previous (i.e. left-most) parameter is to be omitted, its position must be represented by a null value for each particular type. Thus for a null string value, one can use "", and for a null Button or Icon, one can use Nothing.Thus if we wanted to omit the buttons parameter (i.e. include only the OK default) and include a warning icon, this would be done as follows:
	result = MessageBox.Show("You must enter a positive value!", _
		"Invalid Value", Nothing , MessageBoxIcon.Warning)
See more on the MessageBox class here.

1 Recall once again that the assignment operator as well as the relational equality operator both use the equal sign (=). In the first code snippet with "result = MessageBox.Show", the equal sign is assignment. In the second code snippet with "MessageBoxButtons.RetryCancel) = DialogResult.Cancel", the equal sign is equality. This is a subtle but extremely important concept.



Next Section: Repetition Structures Table of Contents


©2007, Mark A. Thomas. All Rights Reserved.