Valid tive C # principle 39: use. Net for verification
Item 39: use. Net Validation
User input may be diverse: You must verify the input as much as possible in interactive controls. Writing user input verification may be tricky, and there may also be errors, but it is still necessary. You cannot trust your input too much. The user may enter any content, resulting in an exception, and then launch an SQL injection attack. We don't want anything like this to happen. You should know enough information to suspect user input. Well, everyone should do this. That's why the. NET Framework has extended such features and you can use these features to make your ownCodeWriting is minimized because we need to verify each piece of data input by the user.
The. NET Framework provides different mechanisms to verify user input, which can be used in Web and Windows applications respectively.Program. Web applications should perform data verification on the browser, generally using JavaScript. Some validation controls generate some js code in the HTML area, which is very effective for your users: they do not need to return data to the service each time they input each item. These Web controls use the regular expression Extension function to verify user input, which can be submitted between the page and the server. Even so, you still need to perform some additional verification on the server to avoid program attacks. In Windows, different modes are used for applications. User input can be verified directly in the application using C # code. All Windows controls are verifiable when you want to notify users of illegal input. The normal mode is to use an attribute access exception to indicate invalid input. The UI control captures these exceptions and displays the error to the user.
You can use five Web controls to process most verification tasks in the Asp.net application. All these five controls control these special fields to be verified by properties. Requiredfieldvalidator forces the user to enter a value in a given field. rangevalidator requires that the value provided by a special field be within the specified range. This range is a number or a string length. Comparevalidator allows you to construct a verification rule to verify two identical controls on the form. These three controls are simple. The last two controls provide powerful functions for you to verify based on the method you want. Regularexpression verification uses a parallel expression to verify user input. If it matches the comparison result, the input is valid. Regular Expressions are useful languages. You can create a regular expression for all your actual situations. Vs.net contains some validation expressions, which can help you learn about it. This is useful information that helps you learn more regular expressions, and I strongly encourage you to learn about it. However, I cannot run the question without providing you with some of the most common structures. Table 5.1 shows some of the most common Regular Expression elements, which you may use in your application to verify the input:
Table 5.1 common Regular Expressions
Build meaning
[A-Z] matches a single lowercase character. Any character in the character set in parentheses matches a single character.
\ D any number.
^, $ ^ Indicates the start of the string, and $ indicates the end.
\ W match any word. This is a [A-Za-z0-9] shorthand.
(? Namedgroup \ D {}) displays two different common elements ,? Namedgroup defines a special variable to reference matching. {4, 16} matches the previous construction at least 4 times and at most 16 times. This pattern matches a string that contains at least four but no more than 16 digits. If a match exists, the results are stored in the namedgroup for later use.
(A | B | C) matches A, B, or C. The selection operation is separated by a solid line: either of the inputs is selected.
(? (Namedgroup) A | B) optional. This is equivalent to the ternary operation in C #. That is to say, if namedgroup exists, it matches a; otherwise, it matches B.
Here is a simple description of the regular expression. I think the regular expressions written by the author here are quite nondescribable, that is, they are neither complete nor refined .)
By constructing these regular expressions, you can find that you can verify any content submitted by the user. If the regular expression is not enough, you can also derive a new verification code from customvalidator to add your own in the class. This is not a small job, and I try to avoid it. After you use C # To write a server function to verify data, you also need to use ecmascript to write a client verification function. I hate doing the same thing twice, and I try to avoid using ecmascript to write anything, so I like to paste regular expressions.
For example, there is a regular expression used to verify the phone number of us. It accepts the area code enclosed in parentheses, or without parentheses, and then the space between the area code and the number, exchange, and number. The horizontal line between the area code and the Exchange Bureau code is also Optional:
(\ S * \ D {3} \ s * \) | (\ D {3 }))-? \ S * \ D {3} \ s *-\ s * \ D {4}
By checking the expressions of each group, the logic is clear:
(\ S * \ D {3} \ s * \) | (\ D {3 }))-?
This matches the area code. It is in the format of (XXX) or XXX, where XXX is three digits. Any blank characters around the number are sufficient. The last two characters,-And ?, It is licensed but does not require a horizontal line.
The rest is used to match the XXX-XXXX part of the phone. \ S matches any blank space, \ D {3} matches three numbers, and \ s *-\ s * matches a blank character surrounding the digit. Finally, \ D {4} precisely matches 4 numbers.
Windows verification works in a slightly different way, and you do not have a pre-verification analysis. Instead, you need to write an event handle to system. windows. forms. control. in the validating event, or, if you have created your own control, reload the onvalidating method (see Principle 35 ). The following is a standard method:
Private void textboxname_validating (Object sender,
System. componentmodel. canceleventargs E)
{
String error = NULL;
// Perform your test
If (textboxname. Text. Length = 0)
{
// If the test fails, set the error string
// And cancel the validation event.
Error = "Please enter a name ";
E. Cancel = true;
}
// Update the state of an error provider
// The correct error text. Set to NULL for no
// Error.
This. errorproviderall. seterror (textboxname, error );
}
You have a few small tasks to complete to make sure that there is no illegal mixing of input into zookeeper. Each control contains a causesvalidation attribute, which determines whether the control participates in verification. In general, you should make this attribute true for all controls unless it is a Cancel button. If you forget it, you must output the correct value before canceling the dialog box. The second small task is to add an OK handle to forcibly verify all controls. Verification is only triggered when the user accesses and leaves the control. If you open a window and click OK immediately, all your verification code will not be executed. To fix this, you need to add an OK button handle to access all controls and then force verify them. The following two general methods show how to complete the task correctly. The Recursive Method processes the Control and Its contained controls: tab page, control group, and control panel:
Private void buttonok_click (Object sender,
System. eventargs E)
{
// Validate everyone:
// Here, this. dialogresult will be set
// Dialogresult. OK
Validateallchildren (this );
}
Private void validateallchildren (control parent)
{
// If validation already failed, stop checking.
If (this. dialogresult = dialogresult. None)
Return;
// For every control
Foreach (control C in parent. Controls)
{
// Give it focus
C. Focus ();
// Try and validate:
If (! This. Validate ())
{
// When invalid, don't let the dialog close:
This. dialogresult = dialogresult. None;
Return;
}
// Validate children
Validateallchildren (C );
}
}
This code can handle most cases. A special quick application is a combination of DataGrid and dataset. Specify the datasource and datamember attributes of errorprovider during design:
Errprovider. datasource = mydataset;
Errprovider. datamember = "Table1 ";
You can also call the bindtodataandrors method to set the parameters at the same time during running:
Errprovider. bindtodataandrerors (mydataset, "Table1 ");
If the datarow. rowerror attribute is set and the datarow. setcolumnerror method is called, a special error is displayed. Errorprovider displays a red warning icon in a special cell on the original row of the DataGrid.
About whirlwind tour.. NET Framework, which may be very helpful to you. In many applications, you can create the efficient verification you need. User input cannot be completely trusted: users may encounter errors, and sometimes some malicious users attempt to destroy your applications. With the services provided by the. NET Framework, you can reduce your coding workload. Verify all user input, but use an efficient tool that has been provided.
==========================================
Item 39: use. Net Validation
User input can come from a variety of locations: You must test input from data files as well as interactive controls. writing user input validation is pedantic and error-prone but very necessary. trusting user input can cause anything from exception conditions to SQL injection attacks. none of the options is pleasant. you know enough to be very skeptical of the validity of user input. good. so does everyone else. that's why. net Framework has extensive capabilities that you can use to minimize the amount of code you need to write, yet still validate every piece of data that your users give you.
The. net Framework provides different mechanisms to validate user input for web-and Windows-based applications. web applications shocould get data validated at the browser, using JavaScript. the validation controls generate Javascript in the HTML page. it's more efficient for your users: they do not need to have round-trips back to the server each time they change an entry. these Web controls make extensive use of regular expressions to tentatively validate user input before the page is posted back to the server. even so, you'll want to perform more extensive validation at the server, to prevent programmatic attacks. windows applications use a different model. user input can be validated in C # code that runs in the same context as the application. the full gamut of Windows controls is available to you when you want to handle y the user of invalid input. the general model uses limits tions in property accessors to indicate the invalid input. ui widgets catch those exceptions and display errors to the user.
You can use five Web controls to handle most of the validation tasks in your asp. NET applications. all five are controlled by properties that specify the field that should be validated and the conditions for valid input. requiredfieldvalidator forces the user to enter some value in a given field. rangevalidator mandates that a specific field supplies a value within a given range. this range cocould be the magncategory of a number or the length of a string value. comparevalidator lets you construct validation rules that relate two different fields in a Web page. these three are relatively simple. the last two give you all the power you need to validate almost any user input you are expecting. the regularexpression validator processes the user input using a regular expression. if the comparison returns a match, the user input is valid. regular Expressions are a very powerful language. you shoshould be able to create a regular expression for any situation you have. visual Studio. net nodes des sample validation expressions that help get you started. there is a wealth of resources to help you learn all about regular expressions, and I strongly encourage you to do that. but I can't leave this topic without giving you a few of the most common constructs. table 5.1 shows the most common Regular Expression elements you'll use for validating input in your applications.
Table 5.1. Common regular expression constructs
Construct meaning
[A-Z] matches any single lowercase letter. Anything inside square brackets matches a single character in the set.
\ D any digit.
^, $ ^ Is the beginning of the line, and $ is the end.
\ W matches any "word" character. It is shorthand for [A-Za-z0-9].
(? Namedgroup \ D {4, 16}) shows two different common elements .? Namedgroup defines a variable that references the match. {4, 16} matches the preceding construct at least 4 times but no more than 16. this pattern matches a string of at least 4 but no more than 16 digits. if a match is found, the match can be referred to later as namedgroup.
(A | B | C) matches any of A, B, or C. Options separated by vertical bars are ored: the input string can contain in any one of them.
(? (Namedgroup) A | B) alternation. This is the equivalent of the ternary operator in C #. It means "If namedgroup exists, match a, else match B ."
Using these constructs and regular expressions, you will find that you can validate just about anything that your users throw at you. if regular expressions aren't enough for you, you can add your own validator by deriving a new class from customvalidator. this is quite a bit of work, And I avoid it whenever I can. you write a server validator function using C #, And then you also write a client-side validator function using ecmascript. I hate writing anything twice. I also avoid writing anything in ecmascript, so I like to stick to regular expressions.
For example, here is a regular expression that validates U. s. phone numbers. it accepts area codes with or without parentheses around them, as well as any number of whitespace between the area code, exchange, and number. A dash between the area code and the exchange is also Optional:
(\ S * \ D {3} \ s * \) | (\ D {3 }))-? \ S * \ D {3} \ s *-\ s * \ D {4}
By examining each group of expressions, the logic is clear:
(\ S * \ D {3} \ s * \) | (\ D {3 }))-?
This matches the area code. It allows either (XXX) or XXX, where XXX is three digits. Any amount of whitespace surrounding the digits is acceptable. The last two characters,-And ?, Allow but do not demand a dash.
The remaining portion matches the XXX-XXXX portion of the phone number. \ s matches any amount of whitespace. \ D {3} matches three digits. \ s *-\ s * matches a dash surrounded by any number of whitespace. finally, \ D {4} matches exactly four digits.
Windows validation works somewhat differently. no precooked validators parse input for you. instead, you need to write an event handler for the system. windows. forms. control. validating event. or, if you are creating your own custom control, override the onvalidating method (see item 35 ). A standard form for a validation event handler follows:
Private void textboxname_validating (Object sender,
System. componentmodel. canceleventargs E)
{
String error = NULL;
// Perform your test
If (textboxname. Text. Length = 0)
{
// If the test fails, set the error string
// And cancel the validation event.
Error = "Please enter a name ";
E. Cancel = true;
}
// Update the state of an error provider
// The correct error text. Set to NULL for no
// Error.
This. errorproviderall. seterror (textboxname, error );
}
you have a few more small tasks to make sure that no invalid input sneaks through. every control contains a causesvalidation property. this property determines whether the control participant in validation. in general, you shoshould leave it true for all of your controls, cannot t for the cancel button. if you forget, the user must create valid input to cancel from your dialog box. the second small task is to add an OK handler to force validation of all controls. validation happens only when a user visits and leaves a control. if the user opens a form and immediately presses OK, none of your Validation Code executes. to fix that, you add an OK button handler to walk through all your controls and force them to validate. the following two routines show you how to do this correctly. the recursive routines handle those controls that are also containers for other controls: tab pages, group boxes, and panels:
Private void buttonok_click (Object sender,
System. eventargs E)
{
// Validate everyone:
// Here, this. dialogresult will be set
// Dialogresult. OK
Validateallchildren (this );
}
Private void validateallchildren (control parent)
{
// If validation already failed, stop checking.
If (this. dialogresult = dialogresult. None)
Return;
// For every control
Foreach (control C in parent. Controls)
{
// Give it focus
C. Focus ();
// Try and validate:
If (! This. Validate ())
{
// When invalid, don't let the dialog close:
This. dialogresult = dialogresult. None;
Return;
}
// Validate children
Validateallchildren (C );
}
}
This code handles most normal cases. A special shortcut cut applies to the DataGrid/dataset combination. Assign the errorprovider's datasource and datamember properties at design time:
Errprovider. datasource = mydataset;
Errprovider. datamember = "Table1 ";
Or, at runtime, call the bindtodataandrerors method to set both in one operation:
Errprovider. bindtodataandrerors (
Mydataset, "Table1 ");
Errors get displayed by setting the datarow. rowerror property and calling the datarow. setcolumnerror method to display specific errors. The errorprovider displays the red exclamation icon on the row and the specific cell in the DataGrid.
This whirlwind tour of the validation controls in the framework shocould help you efficiently create the validation you need in your applications. user input cannot be trusted: users make mistakes, and occasionally malicious users try to break your application. by making the most use of the services already provided by. net Framework, you reduce the code you need to write. validate all user input, but do it efficiently with the tools already provided.