1. Trang chủ
  2. » Công Nghệ Thông Tin

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

7 284 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Validate data passed to properties and communicate errors to developers
Định dạng
Số trang 7
Dung lượng 21,69 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

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

Trang 1

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

Trang 2

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

Trang 3

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.")

Trang 4

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

Trang 5

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

Trang 6

' Strip out any leading or trailing spaces

pstrID = pstrID.Trim

' A CustomerID must have five characters

If pstrID.Length = 5 Then

Return True

Else

Return False

End If

End Function

8 Now add code like that in Listing 9.40 to your constructor that validates the

CustomerID, and, if that value is invalid, throws an InvalidCustomerIDException

Listing 9.40 frmHowTo9_6.vb: An If Then Block to Wrap Around Your Constructor Code

If ValidateCustomerID(pCustomerIDToRetrieve) Then

' Your original constructor code goes here

Else

Throw New InvalidCustomerIDException(pCustomerIDToRetrieve)

End If

9 The final piece of validation code you need to add is a function that checks for the existence of a CustomerID before a new Customer object is instantiated You could use the data access objects you defined in CCustomerData, but for

performance purposes, you should create a new command object and use the ExecuteScalar method as shown in Listing 9.41; this method requires less

interaction with the database

Listing 9.41 frmHowTo9_6.vb: The DoesCustomerIDExist Function

Private Function DoesCustomerIDExist(ByVal pstrID As String) As Boolean

Dim strSQL As String = "SELECT COUNT(*) FROM Customers " & _

"WHERE CustomerID = '" &

pstrID & "'"

Dim cmd As New System.Data.OleDb.OleDbCommand(strSQL, oleCnn) Dim fExists As Boolean

Trang 7

oleCnn.Open()

fExists = CBool(cmd.ExecuteScalar())

oleCnn.Close()

Return fExists

End Function

Add an extra If Then block in the constructor used to create a new Customer row and you're ready to start testing your new code

Your existing code for frmHowTo9_6 should suffice for testing You made sure to handle exceptions thrown from properties in section 9.2

How It Works

Much of the code in this section qualifies and extends the properties you have already defined and implemented This section has two key concepts

Validating data is a critical part of any application, although the examples in this section use validation techniques you should already be familiar with The next section will take data validation to a new level

The most important concept is declaring your own exceptions Communicating errors to other parts of the application is, perhaps, more important than the business logic you implement When it works, it works, but when something goes wrong, providing enough information about the error is far more important Creating new exceptions is an elegant and readable way to communicate and handle errors

Comments

Hardcoding the maximum column length into the property set block as recommended in this section isn't necessarily the best solution to this problem If you decide to increase or decrease the length of the column in the database, you must search through all of your source code to find every place that value was hard coded Using constants is one way around this, but your options still are fairly limited

The strongly typed dataset you created earlier has the potential to provide an elegant solution to this problem The XSD that underlies the dataset could define many of the data rules in your tables, including the maximum length of columns Also, the actual dataset exposes this information in its properties and methods The problem is that Visual Studio NET does not generate XSDs with such strict definitions

Ngày đăng: 24/12/2013, 06:17

TỪ KHÓA LIÊN QUAN