Tải bản đầy đủ (.pdf) (7 trang)

Tài liệu Validate Data Passed to Properties and Communicate Errors to Developers pdf

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (21.69 KB, 7 trang )

9.6 Validate Data Passed to Properties and Communicate Errors to Developers
To make a class that wraps up access to a table, it is critical that the class-and not the
developer who is using the class-makes sure that all data is valid before writing it to the
database.
For example, in the Customers table, the CustomerID field must be five characters in
length-no more, no less-and, of course, it must be unique.
Phone numbers and fax numbers must also be validated. Although we don't necessarily
know how many digits are in a phone number (France has eight-digit numbers, Spain has
nine, and the U.S. has ten), we do know that only numbers and characters such as
periods, parentheses, and hyphens are allowed.
You also need to communicate with other developers when their data is not valid. It is the
data class's job to make sure that invalid data doesn't make it to the database.
This section presents three tasks: adding code to make sure that data passed to an object
matches the column properties in the database, adding code that validates complex data
types and business rules, and communicating errors to the class's consumers.
Technique
First, you need to pass errors back up the call stack. In Visual Basic 6, the accepted
method was to use Err.Raise, which propagates an error number and an error message.
This technique is still available to Visual Basic developers, but it retains all the old
problems. If you aren't careful, programmers who are working on different components
can raise the same error numbers, making error handling a potential nightmare. (If you
aren't careful, you can end up raising the same error number in your own code.)
You learned how to use structured exception handling in earlier chapters, but the beauty
is that you can define your own exceptions as needed, with almost no code. Also, because
exceptions have a name as opposed to a number, it is far easier for developers to work
with your code. Finally, because exceptions are defined with a Namespace, even if two
projects define an InvalidCustomerIDException, each exception will be unique.
Second, you need to write code to check whether a value is valid. For the CustomerID,
you simply need to check the length of the string. (Later on, you'll need to add code to
check whether the ID already exists.) For phone numbers, you'll need to examine the
string for invalid characters.


Steps
Because validating the maximum allowable length for all of our properties is simplest,
tackle this task first.
1. Define a new exception class by inheriting from System.ApplicationException. As
mentioned before, Microsoft recommends that all custom exceptions inherit from
ApplicationException rather than Exception. System.ApplicationException has
most of the methods and properties that you will need to communicate an
exception to consumers of this class. The only property that a consumer might find
useful is one that exposes what the maximum length of the property is. This would
allow the consumer to communicate the error back to the user or truncate the
string without having to hard-code the maximum length into his code. Adding the
name of the property and the value is also a good idea. Some developers who are
using your class might write one long Try...Catch block, so this information will
help debug going forward. Paste the code in Listing 9.33 defining the
MaximumStringLengthExceededException into your code.
Listing 9.33 frmHowTo9_6.vb: Class Declaration for the
MaximumStringLengthExceededException
Public Class MaximumStringLengthExceededException
Inherits System.ApplicationException

Private nMaxLen As Integer

Public Sub New(ByVal pMaxLen As Integer, ByVal pPropertyName As String,
ByVal pValue As String)
' You need to initialize the base class of this exception.
' If you do not specifically call a constructor of the base
' class, the default constructor (the one without parameters)
' will be called, if it exists. MyBase must precede the call to
' the base class's constructor so that the .NET runtime knows not
' to call a constructor in the derived class.

MyBase.new("The value specified, " & pValue & _
", exceeds the maximum " &
"length of " & pMaxLen & " allowable by the " & _
pPropertyName & " property.")
End Sub

Public ReadOnly Property MaxLength() As Integer
Get
Return nMaxLen
End Get
End Property
End Class
2. Next, modify the set block of each property in the class to check the length of the
new value to see if it exceeds the maximum length of the column in the Customers
table. If the length of the new value does exceed the maximum length, throw a
new instance of the MaximumStringLengthExceededException. To do this, simply
create an If...Then block that checks the maximum length into your class.
When you have modified all of your properties, they should look like the
ContactName property in Listing 9.34.
Listing 9.34 frmHowTo9_6.vb: The ContactName Property Validates for the
Maximum Length of the Column and Throws an Exception if the Value
Passed to the Property Exceeds That Maximum Value
Public Property ContactName() As String Implements
ICustomer9_6.ContactName
Get
Return mstrContactName
End Get
Set(ByVal Value As String)
If Value.Length <= 30 Then
mstrContactName = Value

Else
Throw New MaximumStringLengthExceededException(30,
"ContactName", Value)
End If
End Set
End Property
3. Validating a phone number or fax number requires more than just checking the
maximum length of the column. You need to make sure that only numbers and
other allowable characters are in the value. First, create a new exception for
invalid phone numbers by adding the code from Listing 9.35 to frmHowTo9_6.vb.
Listing 9.35 frmHowTo9_6.vb: The InvalidPhoneNumberException
Public Class InvalidPhoneNumberException
Inherits System.ApplicationException

Public Sub New(ByVal pstrPhone As String)
MyBase.New("The phone number specified, " & pstrPhone & ", is not
valid.")
End Sub

End Class
4. Next, add a private method called ValidatePhoneNumber to check a phone number
string for invalid characters, such as letters or punctuation marks, as shown in
Listing 9.36.
Listing 9.36 frmHowTo9_6.vb: A Function That Validates Phone Numbers
Private Function ValidatePhoneNumber(ByVal pstrPhone As String) As Boolean

' Create a string array that contains the numbers 0 to 9, as well as
' a hyphen, period, space, and parentheses.
Dim cValidChars() As String
cValidChars = New String(14) {"1", "2", "3", "4", "5", _

"6", "7", "8", "9", "0", "(", ")", "-", " ", "."}

Dim i As Integer = 0
Dim nUBound As Integer = cValidChars.GetUpperBound(0)
Dim nLBound As Integer = cValidChars.GetLowerBound(0)

' Loop through the array of valid characters and remove them
' from a phone number string. If characters are left
' in the string, the phone number is invalid.
For i = nLBound To nUBound Step 1
pstrPhone = pstrPhone.Replace(cValidChars(i), "")
Next
pstrPhone = pstrPhone.Trim()
If pstrPhone.Length > 0 Then
Return False
Else
Return True
End If

End Function
5. Modify the set blocks of the Fax and Phone properties to call the
ValidatePhoneNumber method and throw an InvalidPhoneNumberException if the
phone number is not valid. Your code should look like Listing 9.37.
Listing 9.37 frmHowTo9_6.vb: The Phone Property That Validates Phone
Numbers
Public Property Phone() As String Implements ICustomer.Phone
Get
Return mstrPhone
End Get
Set(ByVal Value As String)

If Value.Length <= 24 Then
If ValidatePhoneNumber(Value) Then
mstrPhone = Value
Else
Throw New InvalidPhoneNumberException(Value)
End If
Else
Throw New MaximumStringLengthExceededException(24, "Phone",
Value)
End If
End Set
End Property
6. The last piece of data that you need to validate is the CustomerID. You need to
validate for the string length, and for new customers, you need to validate for the
uniqueness of the proposed CustomerID.
Validating for the proper length of a CustomerID is simple. First, add a new
exception called InvalidCustomerIDException, as shown in Listing 9.38.
Listing 9.38 frmHowTo9_6.vb: Declaration of the
InvalidCustomerIDException
Public Class InvalidCustomerIDException
Inherits System.ApplicationException

Public Sub New(ByVal pstrID As String)
MyBase.New("The customer ID specified, " & pstrID & ", is not valid")
End Sub

End Class
7. Then add the method from Listing 9.39, which checks the length of a CustomerID
string and ensures that the string has no whitespace.
Listing 9.39 frmHowTo9_6.vb: The ValidateCustomerID Method

Private Function ValidateCustomerID(ByVal pstrID As String) As Boolean

×