![]() |
|
|
Published: Thursday, May 13, 2004
Copyright © 2004 SitePoint Pty. Ltd. Table of Contents As you learned at the end of the last chapter, one of the great things about ASP.NET is that we can pick and choose which of the various .NET languages we like. In this chapter, we’ll look at some key programming principles using our two chosen languages, VB.NET and C#. We’ll start off with a run-down of some basic programming concepts as they relate to ASP.NET using both languages. We’ll introduce programming fundamentals such as control and page events, variables, arrays, functions, operators, conditionals, and loops. Next, we’ll dive into namespaces and address the topic of classes—how they’re exposed through namespaces, and which you’ll use most often. The final sections of the chapter cover some of the ideas underlying modern, effective ASP.NET design, starting with that of code-behind and the value it provides by helping us separate code from presentation. We finish with an examination of how object-oriented programming techniques impact the ASP.NET developer. One of the building blocks of an ASP.NET page is the application logic: the actual programming code that allows the page to function. To get anywhere with this, you need to grasp the concept of events. All ASP.NET pages will contain controls, such as text boxes, check boxes, lists, and more, each of these controls allowing the user to interact with it in some way. Check boxes can be checked, lists can be scrolled, items on them selected, and so on. Now, whenever one of these actions is performed, the control will raise an event. It is by handling these events with code that we get our ASP.NET pages to do what we want. For instance, say a user clicks a button on an ASP.NET page. That button (or, strictly, the ASP.NET Button control) raises an event (in this case it will be the Click event). When the ASP.NET runtime registers this event, it calls any code we have written to handle it. We would use this code to perform whatever action that button was supposed to perform, for instance, to save form data to a file, or retrieve requested information from a database. Events really are key to ASP.NET programming, which is why we’ll start by taking a closer look at them. Then, there’s the messy business of writing the actual handler code, which means we need to check out some common programming techniques in the next sections. Specifically, we’re going to cover the following areas:
It wouldn’t be practical, or even necessary, to cover all aspects of VB.NET and C# in this book, so we’re going to cover enough to get you started, completing the projects and samples using both languages. Moreover, I’d say that the programming concepts you’ll learn here will be more than adequate to complete the great majority of day-to-day Web development tasks using ASP.NET. As I just mentioned, an event (sometimes more than one) is raised, and handler code is called, in response to a specific action on a particular control. For instance, the code below creates a server-side button and label. Note the use of the OnClick attribute on the Button control: Example 3.1. ClickEvent.aspx (excerpt) <form runat="server">
<asp:Button id="btn1" runat="server" OnClick="btn1_Click"
Text="Click Me" />
<asp:Label id="lblMessage" runat="server" />
</form>When the button is clicked, it raises the Click event, and ASP.NET checks the OnClick attribute to find the name of the handler subroutine for that event. Here, we tell ASP.NET to call the btn1_Click() routine. So now we have to write this subroutine, which we would normally place within a code declaration block inside the <head> tag, like this: Example 3.2. ClickEvent.aspx (excerpt) <head>
<script runat="server" language="VB">
Public Sub btn1_Click(s As Object, e As EventArgs)
lblMessage.Text = "Hello World"
End Sub
</script>
</head>Example 3.3. ClickEvent.aspx (excerpt) <head>
<script runat="server" language="C#">
public void btn1_Click(Object s, EventArgs e) {
lblMessage.Text = "Hello World";
}
</script>
</head>This code simply sets a message to display on the label that we also declared with the button. So, when this page is run and users click the button, they’ll see the message "Hello World" appear next to it. I hope you can now start to come to grips with the idea of control events and how they’re used to call particular subroutines. In fact, there are many events that your controls can use, some of which are only found on certain controls—not others. Here’s the complete set of attributes the Button control supports for handling events:
Don’t worry too much about the intricacies of all these events and when they happen; I just want you to understand that a single control can produce a number of different events. In the case of the Button control, you’ll almost always be interested in the Click event, as the others are only useful in rather obscure circumstances. When a control raises an event, the specified subroutine (if there is one) is executed. Let’s now take a look at the structure of a typical subroutine that interacts with a Web control: Public Sub mySubName(s As Object, e As EventArgs) ' Write your code here End Sub public void mySubName(Object s, EventArgs e) {
// Write your code here
}Let’s break down all the components that make up a typical subroutine:
As this chapter progresses, you’ll see how subroutines associated with particular events by the appropriate attributes on controls can revolutionize the way your user interacts with your application. Until now, we’ve considered only events that are raised by controls. However, there is another type of event—the page event. The idea is the same as for control events[3], except that here, it is the page as a whole that generates the events. You’ve already used one of these events: the Page_Load event. This event is fired when the page loads for the first time. Note that we don’t need to associate handlers for page events the way we did for control events; instead, we just place our handler code inside a subroutine with a preset name. The following list outlines the page event subroutines that are available:
The order in which the events are listed above is also the order in which they’re executed. In other words, the Page_Init event is the first event raised by the page, followed by Page_Load, Page_PreRender, and finally Page_UnLoad. The best way to illustrate the Page_Load event is through an example: Example 3.4. PageEvents.aspx (excerpt) <html> <head> <script runat="server" language="VB"> Sub Page_Load(s As Object, e As EventArgs) lblMessage.Text = "Hello World" End Sub </script> </head> <body> <form runat="server"> <asp:Label id="lblMessage" runat="server" /> </form> </body> </html> Example 3.5. PageEvents.aspx (excerpt) <html>
<head>
<script runat="server" language="C#">
void Page_Load(Object s, EventArgs e) {
lblMessage.Text = "Hello World";
}
</script>
</head>
<body>
<form runat="server">
<asp:Label id="lblMessage" runat="server" />
</form>
</body>
</html>You can see that the control on the page does not specify any event handlers. There’s no need, because we’re using the special Page_Load subroutine, which will be called when the page loads. As the page loads, it will call the Page_Load routine, to display “Hello World” in the Label control, as shown in Figure 3.1. Variables are fundamental to programming, and you’ve almost certainly come across the term before. Basically, they let you give a name, or identifier, to a piece of data; we can then use that identifier to store, modify, and retrieve the data. However, there are, of course, many different kinds of data, such as strings, integers (whole numbers), and floating point numbers (fractions or decimals). Before you can use a variable in VB.NET or C#, you must specify what type of data it can contain, using keywords such as String, Integer, Decimal, and so on, like this: Dim strName As String Dim intAge As Integer string strName; int intAge; These lines declare what type of data we want our variables to store, and are therefore known as variable declarations. In VB.NET, we use the keyword Dim, which stands for “dimension”, while in C#, we simply precede the variable name with the appropriate data type. Sometimes, we want to set an initial value for variables that we declare; we can do this using a process known as initialization: Dim strCarType As String = "BMW" string strCarType = "BMW"; We can also declare and/or initialize a group of variables of the same type all at once: Dim strCarType As String, strCarColor = "blue", strCarModel string strCarType, strCarColor = "blue", strCarModel; Table 3.1 below lists the most useful data types available in VB.NET and C#. Table 3.1. A List of the Commonly Used Data Types
There are many more data types that you may encounter as you progress, but this list provides an idea of the ones you’ll use most often. So, to sum up, once you’ve declared a variable as a given type, it can only hold data of that type. You can’t put a string into an integer variable, for instance. However, there are frequently times when you’ll need to convert one data type to another. Have a look at this code: Dim intX As Integer Dim strY As String = "35" intX = strY + 6 int intX; String strY = "35"; intX = strY + 6; Now, while you or I might think that this could make sense—after all, the string strY does contain a number, so we may well wish to add it to another number—the computer will not be happy, and we’ll get an error. What we have to do is explicitly convert, or cast, the string into an integer first: Dim intX As Integer Dim strY As String = "35" intX = Int32.Parse(strY) + 6 int intX; String strY = "35"; intX = Convert.ToInt32(strY) + 6; Now, the computer will be happy, as we’ve told it that we want to turn the string into an integer before it’s used as one. This same principle holds true when mixing other types in a single expression. Arrays are a special variety of variable tailored for storing related items of the same data type. Any one item in an array can be accessed using the array’s name, followed by that item’s position in the array (its offset). Let’s create a sample page to show what I mean: <html> <head> <script runat="server" language="VB"> Sub Page_Load() ' Declare an array Dim drinkList(4) As String ' Place some items in it drinkList(0) = "Water" drinkList(1) = "Juice" drinkList(2) = "Soda" drinkList(3) = "Milk" ' The line below accesses an item in the array by its position lblArrayList.Text = drinkList(1) End Sub </script> </head> <body> <form runat="server"> <asp:Label id="lblArrayList" runat="server"/> </form> </body> </html> <html>
<head>
<script runat="server" language="C#">
void Page_Load() {
// Declare an array
String[] drinkList = new String[4];
// Place some items in it
drinkList[0] = "Water";
drinkList[1] = "Juice";
drinkList[2] = "Soda";
drinkList[3] = "Milk";
// The line below accesses an item in the array by its position
lblArrayList.Text = drinkList[1];
}
</script>
</head>
<body>
<form runat="server">
<asp:Label id="lblArrayList" runat="server"/>
</form>
</body>
</html>There are some important points to pick up from this code. First, notice how we declare an array. In VB.NET, it looks like a regular declaration for a string, except that the number of items we want the array to contain is given in brackets after the name: In C#, it’s a little different. First, we declare that drinkList is an array by following the datatype with two empty square brackets. We must then specify that this is an array of four items, using the new keyword: A crucial point to realize here is that the arrays in both C# and VB.NET are what are known as zero-based arrays. This means that the first item actually has position 0, the second has position 1, and so on, through to the last item, which will have a position that’s one less than the size of the array (3, in this case). So, we specify each item in our array like this: Example 3.10. Arrays.aspx (excerpt) drinkList(0) = "Water" drinkList(1) = "Juice" drinkList(2) = "Soda" drinkList(3) = "Milk" Example 3.11. Arrays.aspx (excerpt) drinkList[0] = "Water"; drinkList[1] = "Juice"; drinkList[2] = "Soda"; drinkList[3] = "Milk"; Notice that C# uses square brackets for arrays, while VB.NET uses standard parentheses. We have to remember that arrays are zero-based when we set the label text to the second item, as shown here: To help this sink in, you might like to try changing this code to show the third item in the list instead of the second. Can you work out what change you’d need to make? That’s right—you only need to change the number given in the brackets to match the position of the new item (don’t forget to start at zero). In fact, it’s this ability to select one item from a list using only its numerical location that makes arrays so useful in programming, as we’ll see as we get further into the book. Functions are exactly the same as subroutines, but for one key difference: they return a value. In VB.NET, we declare a function using the Function keyword in place of Sub, while, in C#, we simply have to specify the return type in place of using void. The following code shows a simple example: Example 3.14. Functions.aspx <html> <head> <script runat="server" language="VB"> ' Here's our function Function getName() as String Return "Zak Ruvalcaba" End Function ' And now we'll use it in the Page_Load handler Sub Page_Load(s As Object, e As EventArgs) lblMessage.Text = getName() End Sub </script> </head> <body> <form runat="server"> <asp:Label id="lblMessage" runat="server" /> </form> </body> </html> Example 3.15. Functions.aspx <html>
<head>
<script runat="server" language="C#">
// Here's our function
string getName() {
return "Zak Ruvalcaba";
}
// And now we'll use it in the Page_Load handler
void Page_Load() {
lblMessage.Text = getName();
}
</script>
</head>
<body>
<form runat="server">
<asp:Label id="lblMessage" runat="server" />
</form>
</body>
</html>Figure 3.2 shows the result in the browser. Figure 3.2. The Page_Load event is raised, the function is called, and the code within the function is executed. ![]() Here’s what’s happening: the line in our Page_Load subroutine calls our function, which returns a simple string that we can then assign to our label. I hope this illustrates what functions are about and how you can use them. In this simple example, we’re merely returning a fixed string (my name), but the function could just as well retrieve the name from a database—or somewhere else. The point is that, regardless of how the function gets its data, we use it (that is, call it) in just the same way. When we’re declaring our function, we must remember to specify the correct return type. Take a look at the following code: ' Here's our function Function addUp(x As Integer, y As Integer) As Integer Return x + y End Function ' And now we use it in Page_Load Sub Page_Load(s As Object, e As EventArgs) lblMessage.Text = addUp(5, 5).ToString() End Sub // Here's our function
int addUp(int x, int y) {
return x + y;
}
// And now we use it in Page_Load
void Page_Load() {
lblMessage.Text = Convert.ToString(addUp(5, 5));
}You can easily adapt the previous example to use this new code and see the results in your browser. Have a look at this code, and see if you can spot what’s different and why. The first thing you might notice is that our function now accepts parameters. Any function or subroutine can take any number of parameters, each of any type (there’s no need for parameter types to match the return type—that’s just coincidental in this example). We can then readily use the parameters inside the function or subroutine just by using the names we gave them in the function declaration (here, we’ve chosen x and y, but we could have chosen different names). The other difference between this and the function declaration we had before is that we now declare our function with a return type of Integer or int, rather than String, because we want it to return a whole number. When we now call the new function, we simply have to specify the required number of parameters, and remember that the function will return a value with the type we specified. In this case, that means we have to convert the integer value it returns to a string, so we can assign it to the label. In VB.NET, we tack .ToString() onto the end of the function call, while in C# we use the Convert.ToString(…). Note the differences in how these two methods are used—converting numbers to strings is a very common task in ASP.NET, so it’s good to get a handle on it early. Don’t be too concerned if you’re a little confused by how these conversions work, though—the syntax will become clear once we discuss the object oriented concepts involved later in this chapter. Again, a complete discussion of functions could take up an entire chapter, but I hope the brief examples here are enough to prepare you for what we’re going to cover in future chapters. Don’t worry too much if you’re still a bit unsure what functions and subroutines are all about right now—they’ll become second nature very quickly. Throwing around values with variables and functions isn’t much use unless you can use them in some meaningful way, and to do this we use operators. An operator is a symbol that has a certain meaning when applied to values. Don’t worry—they’re nowhere near as scary as they sound! In fact, in the last example, when our function added two numbers, we were using an operator—the addition operator, +. Most of the other available operators are just as well known, although there are one or two that will probably be new to you. Table 3.2 outlines the operators that you’ll use most often. Table 3.2. ASP.NET Operators
The following code uses some of these operators: If (user = "Zak" And itemsBought <> 0) Then lblMessage.Text = "Hello Zak! Do you want to proceed to " & _ "checkout?" End If if (user == "Zak" && itemsBought != 0) { lblMessage.Text = "Hello Zak! Do you want to proceed to " + "checkout?"; } Here, we use the equality, inequality (not equals to) and logical ‘and’ operators in an If statement to print a message only for a given user, and only when he or she has bought something. Of particular note is C#’s equality operator, ==, which is used when comparing two values to see if they are equal. Don’t use a single equals sign in C# unless you are assigning a value to a variable, or your code will have a very different meaning than you expect! Breaking Long Lines of CodeSince the message string in the above example was too long to fit on one line in this book, I also used the string concatenation operator to combine two shorter strings on separate lines to form the complete message. In VB.NET, I also had to break one line of code into two using the line continuation symbol (_, an underscore at the end of the line to be continued). Since C# marks the end of each command with a semicolon (;), I can split a single command over two lines without having to do anything special. I’ll use these techniques throughout this book to show long lines of code within a limited page width. Feel free to recombine the lines in your own code if you like—there is no actual length limit on lines of code in VB.NET and C#. As you develop ASP.NET applications, there will be many instances in which you’ll need to perform an action only if a certain condition is met, for instance, if the user has checked a certain checkbox, selected a certain item from a DropDownList control, or typed a certain string into a TextBox control. We check for such things using conditionals, the simplest of which is probably the If statement. This statement is often used in conjunction with an Else statement, which specifies what should happen if the condition is not met. So, for instance, we may wish to check if the name entered in a text box is "Zak," redirecting to one page if it is, or else redirecting to an error page: If (txtUsername.Text = "Zak") Then
Response.Redirect("ZaksPage.aspx")
Else
Response.Redirect("errorPage.aspx")
End Ifif (txtUsername.Text == "Zak") {
Response.Redirect("ZaksPage.aspx");
} else {
Response.Redirect("errorPage.aspx");
}Often, we want to check for one of many possibilities, and perform a particular action in each case. In that event, we can use the Switch Case (VB.NET) or switch (C#) construct: Dim strName As String = txtUsername.Text
Select Case strName
Case "Zak"
Response.Redirect("ZaksPage.aspx")
Case "Mark"
Response.Redirect("MarksPage.aspx")
Case "Fred"
Response.Redirect("FredsPage.aspx")
Case Else
Response.Redirect("errorPage.aspx")
End Selectstring strName = txtUsername.Text;
switch (strName) {
case "Zak":
Response.Redirect("ZaksPage.aspx");
break;
case "Mark":
Response.Redirect("MarksPage.aspx");
break;
case "Fred":
Response.Redirect("FredsPage.aspx");
break;
default:
Response.Redirect("errorPage.aspx");
break;
}As you’ve just seen, an If statement causes a code block to execute once if the value of its test expression is true. Loops, on the other hand, cause a code block to execute repeatedly for as long as the test expression remains true. There are two basic kinds of loop: A While loop is the simplest form of loop; it makes a block of code repeat for as long as a particular condition is true. Here’s an example: Dim Counter As Integer = 0 Do While Counter <= 10 ' Convert out Integer to a String lblMessage.Text = Counter.ToString() ' Below we use the += operator to increase our variable by 1 Counter += 1 Loop int counter = 0;
while (counter <= 10) {
// Below we use a sneaky way to convert our int to a string
lblMessage.Text = counter + "";
// C# has the operator ++ to increase a variable by 1
counter++;
}You can try out this code—enter it inside a Page_Load subroutine of one of the pages you’ve already created. The page illustrating Page_Load at the start of this chapter would be ideal. Make sure you remove any other code in the subroutine, and that there is an ASP.NET Label control in the HTML of the page with the ID lblMessage. When you open the page, the label will be set to show the number 0, then 1, then 2, all the way to 10. Of course, since all this happens in Page_Load (i.e. before any output is sent to the browser), you’ll only see the last value assigned, 10. This demonstrates that the loop repeats until the condition is no longer met. Try changing the code so that the counter variable is initialized to 20 instead of 10. When you open the page now, you won’t see anything on screen, because the loop condition was never met. There is another form of the While loop, called a Do While loop, which checks if the condition has been met at the end of the code block, rather than at the beginning: Dim Counter As Integer = 0 Do ' Convert our Integer to a String lblMessage.Text = Counter.toString() ' Below we use the += operator to increase our variable by 1 Counter += 1 Loop While Counter <= 10 int counter = 0;
do {
// Below we use a sneaky way to convert our int to a string
lblMessage.Text = counter + "";
// C# has the operator ++ to increase a variable by 1
counter++;
} while (counter <= 10);If you run this code, you’ll see it provides the exact same output we saw when we tested the condition before the code block. However, we can see the crucial difference if we again change it so the counter variable is initialized to 20. In this case, we will, in fact, see 20 on screen, because the loop code is executed once before the condition is even checked! There are some instances when this is just what we want, so being able to place the condition at the end of the loop can be very handy. A For loop is similar to a While loop, but is typically used when the number of times we need it to execute is known beforehand. The following example displays the count of items within a DropDownList control called ddlProducts: Dim i As Integer For i = 1 To ddlProducts.Items.Count lblMessage.Text = i.toString() Next int i;
for (i = 1; i <= ddlProducts.Items.Count; i++) {
lblMessage.Text = Convert.ToString(i);
}In VB.NET, the loop syntax specifies the starting and ending values for our counter variable in the For statement itself. In C#, we assign a starting value (i = 1), a condition to be tested each time through the loop, just like a While loop (i <= ddlProducts.Items.Count), and how the counter variable should be incremented after each loop (i++). While this allows for some powerful variations on the theme in C#, it can be confusing at first. In VB.NET, the syntax is considerably simpler, but can be a bit limiting in exceptional cases. The other type of For loop is For Each, which loops through every item within a collection. The following example loops through an array called arrayName: For Each item In arrayName lblMessage.Text = item Next foreach (string item in arrayName) {
lblMessage.Text = item;
}You may also come across instances in which you need to exit a loop prematurely. In this case, you would use Exit (VB.NET) or break (C#) to terminate the loop: Dim i As Integer
For i = 0 To 10
If (i = 5) Then
Response.Write("Oh no! Not the number 5!!")
Exit For
End If
Nextint i;
for (i = 0; i <= 10; i++) {
if (i == 5) {
Response.Write("Oh no! Not the number 5!!");
break;
}
}In this case, as soon as our For loop hits 5, it displays a warning message, using the Response.Write() method that will be familiar to those with past ASP experience, and exits the loop so that no further passes through the loop will be made. Although we have only scratched the surface, VB.NET and C# provide a great deal of power and flexibility to the Web developer, and time spent learning the basics now will more than pay off in the future.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
![]() |
![]() |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||