C# Developeramp;#039;s Guide to ASP.NET, XML, and ADO.NET [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

C# Developeramp;#039;s Guide to ASP.NET, XML, and ADO.NET [Electronic resources] - نسخه متنی

Jeffrey P. McManus; Chris Kinsman

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید









Creating Web Forms for Data Entry



Now that you have a sense of how to retrieve and manipulate data using ADO.NET, you''ll need to have a strategy for building user interfaces in ASP.NET to access database functionality.


Like other Web-programming paradigms, the process of inserting or updating data through a Web browser typically involves constructing an HTML form that contains an array of input controls. The user inserts or changes values in the controls on the form and then submits the form to the Web server. The server passes the form contents to a script that then forms the actual data operation.


Listing 11.14 shows a simple example of an ASP.NET page that facilitates data entry.


Listing 11.14 Simple Data-Entry Form


<% @Page language=''c#'' debug=''true'' trace=''false'' %>
<% @Import namespace=''System.Data'' %>
<% @Import namespace=''System.Data.SqlClient'' %>
<SCRIPT runat=''server''>
void Page_Load(Object Sender,EventArgs e)
{
if(Page.IsPostBack)
{
SqlConnection cn;
SqlCommand cm;
String strSQL;
cn = new SqlConnection("server=localhost;uid=sa;pwd=;database=pubs;");
strSQL = "INSERT INTO authors " +
"(au_id, au_fname, au_lname, contract) " +
"VALUES (''" + txtID.Text + "'', ''" +
txtFirstName.Text + "'', ''" +
txtLastName.Text + "'', ''" +
ChkToInt(chkContract) + "'')";
cm = new SqlCommand(strSQL, cn);
// ** Open connection
try
{
cn.Open();
// ** Execute command
cm.ExecuteNonQuery();
}
catch(SqlException sx)
{
Response.Write("Exception Occurred: " + sx.Message);
}
finally
{
if (cn.State == ConnectionState.Open)
cn.Close();
}
// ** Execute command
Trace.Write("Command: " + cm.CommandText);
// ** Clear form for next item
txtID.Text = ";
txtFirstName.Text = ";
txtLastName.Text = ";
chkContract.Checked = false;
}
}
int ChkToInt(CheckBox chk)
{
if(chk.Checked)
return 1;
else
return 0;
}
</SCRIPT>
<html>
<head>
<title>ASP.NET Data Entry</title>
</head>
<body bgcolor="#FFFFFF" text="#000000">
<FORM runat=''server''>
<table width="300" border="0">
<tr>
<td>ID: </td>
<td>
<asp:textbox id="txtID" runat=''server'' />
</td>
</tr>
<tr>
<td>First Name: </td>
<td>
<asp:textbox id="txtFirstName" runat=''server'' />
</td>
</tr>
<tr>
<td>Last Name:</td>
<td>
<asp:textbox id="txtLastName" runat=''server'' />
</td>
</tr>
<tr>
<td>Contract:</td>
<td>
<asp:checkbox id="chkContract" runat=''server'' />
</td>
</tr>
</table>
<p>
<asp:button id="btnSave" text="Save" runat=''server'' />
</p>
</FORM>
</body>
</html>


This page takes the code used to perform a nonquery command (introduced earlier in this chapter) and attaches a simple user interface to it. Although it is minimal, the pattern set by this example, in Listing 11.8, forms the basis of a great deal of Web-based data entry forms in ASP.NET.


The Page_Load event procedure performs the work involved in inserting the data into the database. Note that the data is sent to the database only if the IsPostBack property of the Page object is true. There''s no point sending data to the database unless there''s something to send. Note, too, that we explicitly cleared the contents of the controls on the form after inserting the data (this circumvents ASP.NET''s default view state behavior).


The only other tricky thing on this page is the ChkToInt function. This function takes the Checked value returned by the CheckBox control and converts it into the 1 or 0 value required by SQL Server.


Two problems occur with this pageboth related to validation. If the user enters an author with the same ID as an existing author, she will get an error. You can get around this problem by catching the SqlException that is thrown when the ExecuteNonQuery method is reached.


The next problem is less straightforward: how to ensure that the user actually enters valid data for the ID, first name, and last name fields. It happens that ASP.NET provides some powerful and flexible components for dealing with this problem. We''ll cover them in the next section.


Performing Validation



Every software application should have code that ensures that data entered by users is valid. Web applications are no different.


In ASP.old, developers typically embedded validation logic in pages that also contained display logic; separating validation logic from presentation logic was tricky, but it was possible. If you were interested in performing a simple validation, such as making sure that a given text box contains a value between 1 and 10, the template-based design of ASP.old practically forced you to embed that validation code on the same page.


Incorporating client-side validation adds a new level of complexity to this problem. Because client-side validation is commonly done using JavaScript (for cross-browser compatibility), this forced you to embed code written in two very different languages in a single page. Madness!


ASP.NET solves this problem by creating language-neutral objects for performing validation. These come in the form of Web Forms server controlsvalidation objects that accept generic rules pertaining to the most common types of data validation. These objects are tightly integrated with the Page object so that when a Web form is submitted to the server, the validation object can communicate to the Page object that the field it validates has not passed the validation rule.


ASP.NET provides six validation objects:




RequiredFieldValidator




CompareValidator




RangeValidator




RegularExpressionValidator




ValidationSummary




CustomValidator





To perform validation, you create the Web form as you normally would and then attach validation controls to the input controls in the form. This is done by setting the validation control''s ControlToValidate property. You can also validate a control against a variable or constant value instead by setting the validation''s ValueToCompare property. You then assign validation parameters where appropriate. (Some validation controls, such as RequiredFieldValidator, don''t need extra validation parameters.)


When the page is submitted to the server, the validation rule contained by the validation control is applied. Validation controls are invisible until their validation rules are violated; if the validation rule fails, an optional error message is displayed. Your code must provide a way to deal with the situation where a validation rule is violated. You can programmatically inspect the IsValid property of the Page object to quickly determine whether one or more validation controls were violated. For complex pages with many validation controls, you can also provide a list of all validation violations on the page; in fact, ASP.NET provides a special object (the ValidationSummary control) to perform this function.


Eight controls that can be associated with validation controls, shown next, ship with ASP.NET.


HTML controls:




HtmlInputText




HtmlTextArea




HtmlSelect




HtmlInputFile





Server controls:




TextBox




ListBox




DropDownList




RadioButtonList





To keep the examples simple, in this section we''ll perform validation against the TextBox server control exclusively. Also, to make these examples briefer and easier to understand, we won''t bother including the actual data access code in the validation examples here; we''ll assume that you''ll include code similar to that described earlier in this chapter to perform the actual database operation required to get your data into the database.


Validation controls work by generating DHTML and JavaScript for browsers that support them, and performing round trips to the server for browsers that do not. This greatly increases the efficiency of validation, ensuring that forms that contain bad data aren''t sent across the network. The best part of this feature is that you don''t have to learn JavaScript to make this client-side validation happen; validation controls can emit the appropriate JavaScript code automatically.


The next few sections describe how to use each validation control in more detail.


Validating for Required Fields


Required field validation forces the user to enter a value in the validated control. It''s one of the easiest validators to implement because it doesn''t require a separate property assignment to determine what the validation rule is. If a RequiredFieldValidator is attached to a control, the field is required and the page isn''t valid unless the user puts something in the field.


Listing 11.15 shows an example of the RequiredFieldValidator control in action.


Listing 11.15 Requiring a Field Using the RequiredFieldValidator Control


<HTML>
<HEAD>
<SCRIPT language="C#" runat="server">
void SaveBtn_Click(Object Sender,EventArgs e)
{
if(Page.IsValid)
lblOutput.Text = "Record saved.";
else
lblOutput.Text = ";
}
</SCRIPT>
</HEAD>
<BODY>
<FORM runat="server" ID="Form1">
<asp:textbox id=TextBox1 runat=server />
<asp:RequiredFieldValidator id="RequiredFieldValidator2"
ControlToValidate="TextBox1"
Display="Static"
Width="100%" runat=server>
Please enter your name.
</asp:RequiredFieldValidator>
<asp:Button id=Button1 text="Save" OnClick="SaveBtn_Click" runat=server />
<asp:label id=''lblOutput'' runat=''server'' />
</FORM>
</BODY>
</HTML>


As you can see from the code, this mode of validation is pretty straightforwardjust specify the control you want to validate in the RequiredFieldValidator''s ControlToValidate property, and then check to see if the page is valid in an event procedure attached to a control that submits the form (in this case, the button called Button1).


One of the main objectives of client validation is to catch bad input before your application performs expensive trips across the network. This example demonstrates how ASP.NET handles this; if you enter bad data, the page will not be submitted to the server.


You might find it illustrative to see how this validation is performed "under the hood" of the browser. To see the client code that is generated by the validation control, navigate to this page and create a validation error by clicking the button without typing anything into the text field. Watch the browser as the error is generated; you should notice that no progress bar is at the bottom of the window to indicate a jump across the network, and the page displays the error message instantly, without having to reload.


Next, use the View Source command to take a look at the HTML code generated by the ASP.NET page. As you scroll through the code, you should be able to see a reference to a JavaScript file called WebUIValidation.js. This file resides on the server (in a directory called \aspnet_client under the IIS root directory) but is downloaded and executed on the client side when a validation control is present in a Web form. The JavaScript function named RequiredFieldValidatorEvaluateIsValid is called when you use a RequiredFieldValidator control (analogous functions exist for the other types of validators). By viewing the script file WebUIValidation.js, you can see how they work. The one for required field validation is monumentally trivialit''s listed in Listing 11.16.


Listing 11.16 Client-Side Validation for Required Field Function


function RequiredFieldValidatorEvaluateIsValid(val) {
return (ValidatorTrim(ValidatorGetValue(val.controltovalidate))
!= _ValidatorTrim(val.initialvalue))
}


This function uses a lot of verbiage to accomplish a simple taskfiguring out whether a value is there. If it''s there, the function returns true; if not, it returns false. Of course, this isn''t so complicated that you couldn''t have written it yourself, but it''s nice that this kind of code is abstracted behind the validator control so that you don''t have to think in two languages just to perform simple validation.


Comparison Validation Using the CompareValidator Control


Comparison validation examines the value of a control and compares it against the value of another control''s property, a variable, or a constant. To use CompareValidator, you must specify three things: the control to validate, the control (or value) to compare it to, and an operator (one of the equality or inequality types).


As an example of this, suppose you''re building a Web form that gives your employees pay raises. The important validation rule with a pay raise calculation is: Don''t accidentally give your employees a pay cut! You can use a CompareValidator control with the greater-than operator to ensure that this is the case. Listing 11.17 shows an example.


Listing 11.17 Performing Comparison Validation in a Data Entry Form


<HTML>
<HEAD>
<TITLE>
Pay Raise Calculator
</TITLE>
<SCRIPT language="C#" runat="server">
void SaveBtn_Click(Object Sender,EventArgs e)
{
if(Page.IsValid)
lblOutput.Text = "The new pay rate is: " + txtNewRate.Text;
else
lblOutput.Text = ";
}
</SCRIPT>
</HEAD>
<BODY>
<FORM runat="server">
Current Rate:<asp:textbox id=txtOldRate text=''3000'' runat=server /><BR>
New Rate:<asp:textbox id=txtNewRate runat=server />
<asp:Button id=Button1 text="Save" OnClick="SaveBtn_Click" runat=server /><BR>
<asp:CompareValidator id="CompareValidator1"
ControlToValidate="txtNewRate"
ControlToCompare="txtOldRate"
Type="Double"
Operator="GreaterThan"
runat="server">
You eeeediot! Do not give your employees a pay cut!
</asp:CompareValidator>
<asp:label id=''lblOutput'' runat=''server'' />
</FORM>
</BODY>
</HTML>


To understand the relationship between ControlToValidate, ControlToCompare, and Operator, think of the three properties as elements of an expression that looks like this:



ControlToCompare Operator ControlToValidate


Hence, if ControlToCompare is 3000, ControlToValidate is 3500, and Operator is "GreaterThan", the expression is true and the page is valid. If ControlToValidate is 0, for example, the expression becomes false and the validation fails.


The legal values for the Operator property for controls that use them are enumerated in System.Web.UI.WebControls.ValidationCompareOperator and are listed in Table 11.3.






































Table 11.3. Members of the ValidationCompareOperator Enumeration Used in Comparison Validation
Member
Description
DataTypeCheck
Returns true if the two values are the same data type
Equal
Returns true if the two values are equal
GreaterThan
Returns true if ControlToValidate is greater than ControlToCompare
GreaterThanEqual
Returns true if ControlToValidate is greater than or equal to ControlToCompare
LessThan
Returns true if ControlToValidate is less than ControlToCompare
LessThanEqual
Returns true if ControlToValidate is less than or equal to ControlToCompare
NotEqual
Returns true if the two controls are not equal


The broad range of operators gives you a great deal of flexibility; however, if you need a validation rule that goes beyond what any of the standard validation controls are capable of, you can always turn to the custom validation control, as seen in Listing 11.20.


Range Validation Using the RangeValidator Object


Range validation forces the data in a given control to fall within a given rangealphabetic, numeric, or date. You specify the boundaries of the range using the control''s MinimumValue and MaximumValue properties. As with the CompareValidator control, you can also denote a data type on which to base the comparison (using the control''s Type property).


Listing 11.18 shows an example of the RangeValidator object in action.


Listing 11.18 Performing Range Validation


<HTML>
<HEAD>
<TITLE>
Pay Raise Calculator [Range]
</TITLE>
<SCRIPT language="C#" runat="server">
void SaveBtn_Click(Object Sender,EventArgs e)
{
if(Page.IsValid)
lblOutput.Text = "The new pay rate is: " + txtNewRate.Text;
else
lblOutput.Text = ";
}
</SCRIPT>
</HEAD>
<BODY>
<FORM runat="server">
Current Rate:<asp:textbox id=txtOldRate text=''3000'' runat=server /><BR>
New Rate:<asp:textbox id=txtNewRate runat=server />
<asp:Button id=Button1 text="Save" OnClick="SaveBtn_Click" runat=server /><BR>
<asp:RangeValidator id="RangeValidator1"
ControlToValidate="txtNewRate"
MinimumValue=''1000''
MaximumValue=''5000''
Type="Double"
runat="server">
Please enter a value between 1000 and 5000.
</asp:RangeValidator>
<asp:label id=''lblOutput'' runat=''server'' />
</FORM>
</BODY>
</HTML>


In this example, we revisit the pay raise calculator. This time, we want to make sure that our human resources executives aren''t too generous or too stingy with our employees. To test this code, navigate to the page and attempt to enter a value less than 1000 or greater than 5000 as a new pay rate. The control will render the page invalid, preventing the data from being processed until you enter a valid amount.


You''ll want to make sure that you always provide an error message that clearly informs the user what the valid range is when using a RangeValidator control. If you can, it''s even better to let the user know what the valid range is initially, before the user has a chance to make an error.


Validation Using Regular Expressions


Regular expressions are a symbolic minilanguage used for text processing. You can use the RegularExpressionValidator control to apply a regular expression comparison to a value in your form. To do this, you assign the regular expression pattern to the ValidationExpression property of the RegularExpressionValidator control.


For example, suppose you''re creating an application that requires users to establish a PIN number when they initially create their account. The rules for your application are that PINs must be composed of a single non-numeric character followed by three numbers. Determining whether a given string is four characters in length is easy in code, but determining whether those digits are numbers or letters may take a bit of doing. Fortunately, it''s easy using a regular expressionthe expression "\D\d\d\d" matches a string comprising a non-digit character followed by three digits. A comparison based on this expression will reject anything larger or smaller than four characters in length.


Listing 11.19 shows an example of how to perform regular expression validation in ASP.NET using this validation rule.


Listing 11.19 Performing Validation Based on a Regular Expression Comparison


<HTML>
<HEAD>
<TITLE>
Account Creation [RegExp]
</TITLE>
<SCRIPT language="C#" runat="server">
void SaveBtn_Click(Object Sender,EventArgs e)
{
if(Page.IsValid)
lblOutput.Text = "Account created!";
else
lblOutput.Text = ";
}
</SCRIPT>
</HEAD>
<BODY>
<FORM runat="server" ID="Form1">
User ID:<asp:textbox id=txtUserID text=''newuser'' runat=server /><BR>
PIN:<asp:textbox id=txtPIN runat=server />
<asp:Button id=Button1 text="Save" OnClick="SaveBtn_Click" runat=server /><BR>
<asp:RegularExpressionValidator id="RegularExpressionValidator1"
ControlToValidate="txtPIN"
ValidationExpression="\D\d\d\d"
runat="server">
Please enter PIN comprising a non-number followed by three numbers.
</asp:RegularExpressionValidator>
<asp:label id=''lblOutput'' runat=''server'' />
</FORM>
</BODY>
</HTML>


To test this code, navigate to the page in a browser and attempt to enter an invalid PIN (such as XXXX) into the PIN field. You should be able to see that any combination of characters that does not match the regular expression will cause the validation rule to fail; a valid entry is a string similar to "A599."



NOTE


A full exploration of the syntax of regular expressions is beyond the scope of this book, but they''re covered adequately in the .NET framework SDK documentation. The seminal book on regular expressions is Jeffrey E. F. Friedl''s Mastering Regular Expressions (O''Reilly). The book is geared toward developers writing scripts using the Perl programming language in Unix, but don''t let that scare you awaythe amount of actual Perl code in the book is very small.


Custom Validation Using the CustomValidator Object


You can use custom validation in situations where your validation is too complicated or irregular for the standard validation controls described in this section.


To implement a custom validation rule using the CustomValidator control, you must write a custom validator function. The cool thing about CustomValidator is that your validation function can reside and execute on either the server side or the client side, or both. (Of course, if cross-browser compatibility is important to you, you will want to write your client-side validation function in JavaScript.) To assign a server-side validation function to a CustomValidator, you write a function and assign the name of the function to the ControlValidator''s OnServerValidate property. To assign a client-side function, write a client function and assign it to the ControlValidator''s ClientValidationFunction property.


To demonstrate this function, we''ll return to the PIN example introduced in the previous example. This time, we''ll assume that the user created an account and is ready to log in. We want to provide custom validation on the client and server side for the PIN field. On the client side, we want to make sure that the PIN is composed of a letter and three numbers; we will use a regular expression in JavaScript to do this. But you wouldn''t want to verify the password using client-side JavaScript, because this technique isn''t secure (JavaScript is executed on the client and is visible to the client). So we''ll perform the actual verification of the PIN on the server.


Listing 11.20 shows an example of custom validation using server-side validation.


Listing 11.20 Performing Custom Validation on the Server Side


<HTML>
<HEAD>
<TITLE>
Login with PIN [Custom Validation]
</TITLE>
<SCRIPT language="C#" runat="server">
void SaveBtn_Click(Object Sender,EventArgs e)
{
if(Page.IsValid)
lblOutput.Text = "Login successful!";
else
lblOutput.Text = ";
}
void ServerVerify(Object Sender, ServerValidateEventArgs Value)
{
// In a real application, this code would do
// a database call or use Active Directory or
// something interesting. For this example, no.
if(txtPIN.Text == "A999")
Value.IsValid = true;
else
Value.IsValid = false;
}
</SCRIPT>
</HEAD>
<BODY>
<FORM runat="server">
User ID:<asp:textbox id=txtUserID text=''myusername'' runat=server /><BR>
PIN:<asp:textbox id=txtPIN runat=server />
<asp:Button id=Button1 text="Save" OnClick="SaveBtn_Click" runat=server /><BR>
<asp:CustomValidator id="CustomValidator1"
ControlToValidate="txtPIN"
OnServerValidate="ServerVerify"
runat="server">
Invalid PIN number!
</asp:CustomValidator>
<asp:label id=''lblOutput'' runat=''server'' />
</FORM>
</BODY>
</HTML>


You can see that the CustomValidator is pretty straightforwardto make it work, you set its OnServerValidate property to the name of the function you want to use to perform the validation. Your code then sets the IsValid property of the ServerValidateEventArgs object passed into the function to either true or false, depending on whether the validation logic contained in the function has validated the data.


To create a client-side validation function, you create a validation function and assign its name to the ClientValidationFunction property of the CustomValidator control. Your function should take two parameters: source and arguments (this is similar to an event procedure declaration). Within the client validation function, you set the value of arguments.IsValid to true or false, depending on the outcome of the validation code.


Also, you can write your client-side validation code in VBScript if cross-browser compatibility isn''t important to you (that is, you know that every user who uses your Web application will be using some version of Microsoft Internet Explorer).


Note that if you don''t want to perform client-side validation for some reason, you can simply omit it, as our code example has done in Listing 11.20.


Providing a Summary of Validation Rule Violations


Summary validation takes the error messages generated by any number of validation controls and displays them in a summary format. The ValidationSummary control can display its output inline on the page or in a pop-up message box. Because it has the capability to give the user multiple error messages at once, it''s very effective in situations where you have many validation controls on a form.


Listing 11.21 shows an example of how summary validation works.


Listing 11.21 Displaying a Summary of Validation Errors


<HTML>
<HEAD>
<TITLE>
Pay Raise Calculator [Summary]
</TITLE>
<SCRIPT language="C#" runat="server">
void SaveBtn_Click(Object Sender, EventArgs e)
{
if(Page.IsValid)
lblOutput.Text = "The new pay rate is: " + txtNewRate.Text;
else
lblOutput.Text = ";
}
</SCRIPT>
</HEAD>
<BODY>
<FORM runat="server" ID="Form1">
<asp:RequiredFieldValidator id="RequiredFieldValidator1"
ControlToValidate="txtName"
ErrorMessage="Please enter an employee name."
runat=server>
*
</asp:RequiredFieldValidator>
Employee Name:<asp:textbox id=txtName runat=server /><BR>
Current Rate:<asp:textbox id=txtOldRate text=''3000'' runat=server /><BR>
<asp:RangeValidator id="RangeValidator1"
ControlToValidate="txtNewRate"
ErrorMessage="Please enter a value between 1000 and 5000."
MinimumValue=''1000''
MaximumValue=''5000''
Type="Double"
runat="server">*</asp:RangeValidator>
New Rate:<asp:textbox id=txtNewRate text=''12.98'' runat=server />
<asp:Button id=Button1 text="Save" OnClick="SaveBtn_Click" runat=server /><BR>
<asp:label id=''lblOutput'' runat=''server'' />
<asp:ValidationSummary id=''ValidationSummary1'' runat=''server''
DisplayMode=''BulletList''
HeaderText=''You Committed Serious Data Validation Crimes:''
ShowSummary=''true''
ShowMessageBox=''true'' />
</FORM>
</BODY>
</HTML>


Here we''ve returned to our pleasant pay raise calculator scenario. This time, we require that the user enter an employee name and a new pay rate (the current pay rate is filled in automatically with a hard-coded value). Two validation controls are on this page: a RequiredFieldValidator attached to the Employee Name field, and a RangeValidator connected to the New Rate field. It would be obnoxious to give users an error message if they failed to enter the employee''s name, only to zap them with another error message when they neglect to enter a new pay rate; the validation summary gives them all the applicable error messages at once. To test this, navigate to the page and click the Save button without changing any of the values on the page.


The combination of red asterisks, warning messages on the page, and the message box alert probably makes this the most annoying data entry form in the history of Web programming, but it''s really all in the name of science. Certainly your production Web forms will be more tasteful.


Using Multiple Validators


It often makes sense to have multiple validators attached to the same control. For example, if a field is required to be present and to fall within a certain range of values, you might attach both a RequiredFieldValidator and a RangeValidator to the control. There''s no trick to this; simply assign as many validators as you need to implement the validation logic you want.


/ 106