AddThis Social Bookmark Button

Print

Top Ten Tips for Programming ASP.NET

by Dan Hurwitz, coauthor of Programming ASP.NET
04/22/2002

Here are ten tips for programmers getting their feet wet with ASP.NET. From changing the default names of controls and forms to using the StringBuilder class, these ideas will help coders make the transition to the .NET environment.

1. Use Visual Studio .NET, but do not use default names for anything except trivial or non-referenced objects.

One of the joys of working with .NET is that all the source code and configuration files are flat text files, and can be easily edited with any text editor, such as Notepad or WordPad. If you don't want to use Visual Studio .NET as your IDE, you don't have to. Even if you do use Visual Studio .NET, there are times when it is very helpful to be able to see the existence of a file in Windows Explorer, or look at the contents of a file in a text editor independently from Visual Studio .NET.

That said, there are many advantages to using Visual Studio .NET. The most significant is vastly improved productivity. Using Visual Studio. NET you will develop your programs more quickly and with less effort. The IntelliSense technology that is part of the IDE provides automatic code completion, dynamic help as you enter a method or function, real-time indication of syntax errors, and a slew of other productivity-enhancing features.

Like any complex tool, Visual Studio .NET can be frustrating until you learn how to use it to full advantage and understand its quirks and hidden features. At times it can seem like an inscrutable black box, creating myriad files and a lot of auto-generated boiler-plate code.

One feature of Visual Studio .NET is its use of default names for new objects, whether the object in question is a form or a class or a control. For example, if you create a new ASP.NET Web Application, the default name will be WebApplication1. You can easily change this in the New Project dialog box, but all that does is change the name of the name space and the virtual directory where the application is created. The source code files will still have the default names WebForm1.aspx and WebForm1.aspx.cs (for a C# project) or WebForm1.aspx.vb (for a VB.NET project).

Related Reading

Programming ASP .NET
By Jesse Liberty, Dan Hurwitz

You can rename the ASPX and code-behind files in the Solution Explorer, but the Web page class name will remain WebForm1. Put a button control on the Web form and it will have the default name Button1. In fact any control will have a default name comprised of the control type and a number.

You can, and should, rename all the controls and forms to something meaningful for your application. Default names are fine for a small demo program, but when a project has several forms, each with many buttons and labels, names such as frmStartup, frmDataEntry, and frmReports are much easier to understand and to maintain than Form1, Form2 and Form3.

It is even more important to rename controls on a form which are referenced elsewhere in code. Names such as btnOK, btnCancel, and btnPrint are immediately meaningful to anyone looking at the code, and thus are far easier to maintain than controls named Button1, Button2, and Button3.

One great way to change all the occurrences of a name in all the files in a project is to use the Edit | Find and Replace | Replace in Files command from the Visual Studio .NET menu.

Alzheimer's Law of Programming: Looking at code you wrote more than two weeks ago is like looking at code you are seeing for the first time.

To help combat this, make sure your controls and forms have meaningful names that help you understand what they do.

2. Even if coding outside of Visual Studio .NET, use code-behind files for a performance benefit the first time a page is requested.

Visual Studio .NET uses code-behind files for any ASP.NET Web project: Web applications, Web services, or Web controls. Code-behind lends itself to projects that are better organized, more modular, and more suitable for multi-person development teams. It also provides a performance boost.

The contents of a code-behind file are compiled into a class in an assembly file, typically a DLL, although it may also be an EXE. This assembly file resides in the application assembly cache on disk (typically the \bin directory) and is immediately available when the application starts.

When the source code is contained inside <script> tags, in line with the ASPX file, the source code is still compiled into a page class. However, in this case, the compilation must occur every time the page is first loaded for an application session. The compiled class is then cached in memory. The file must be recompiled each time the machine is rebooted, IIS is stopped and restarted, or a source or configuration file is modified. This is a small, but very noticeable performance hit.

3. Test for postback on page load.

Every time a Button, LinkButton, or ImageButton is clicked on a Web page, the form is posted back to the server. Many other controls, such as CheckBox and CheckBoxList, will also cause a form to post back to the server when a change is made to the state of the control, if the AutoPostBack property of the control is set to true.

Every time a form is posted back to the server, it is reloaded and the Page_Load event fires, causing any code in the Page_Load event handler to execute. This is an excellent place to put initialization code for the page. However, you often want some code to execute every time the page loads, other code to execute only the first time the page loads, and even other code to execute every time the page loads except the first time.

This can be accomplished using the IsPostBack property. This property is false the first time the page is loaded. If the page is reloaded due to a postback, the IsPostBack property is true. By testing, you can cause specific lines of code to execute only when desired. Consider the following code snippet (in C#):


   protected void Page_Load(Object sender, EventArgs e) 
   {
      //  Do stuff here every time the page loads
      if (!IsPostBack)
     {
         //  Do stuff here the first time the page loads only
      }
      else
      {
         //  Do stuff here on postback only
      }
      
      //  Do more stuff here every time the page loads
   }

You want to postback as seldom as possible (each postback requires a round trip to the server) and when you do postback you want to do as little work as possible. Large, time-consuming operations (such as database look-ups) should be especially avoided, because they drive down the responsiveness of your program.

4. Use the StringBuilder class.

Strings are immutable in the .NET framework. This means that methods and operators which appear to change the string are actually returning a modified copy of the string. This has significant performance implications. When doing a lot of string manipulation, it is much better to use the StringBuilder class.

Consider the code shown in the following code listing (in C#). It measures the time to create a string from 10,000 substrings in two different ways. The first time, a simple string concatenation is used; the second time the StringBuilder class is used. To see the resulting string, uncomment the two commented lines in the code.


<%@ Page Language="C#" %>

<script runat="server">
   void Page_Load(Object Source, EventArgs E)
   {
      int intLimit = 10000;
      DateTime startTime;
      DateTime endTime;
      TimeSpan elapsedTime;
      string strSub;
      string strWhole = "";

      //  Do string concat first
      startTime = DateTime.Now;
      for (int i=0; i < intLimit; i++)
      {
         strSub = i.ToString();
         strWhole = strWhole + " " + strSub;
      }
      endTime = DateTime.Now;
      elapsedTime = endTime - startTime;
      lblConcat.Text = elapsedTime.ToString();
//      lblConcatString.Text = strWhole;

      //  Do stringBuilder next
      startTime = DateTime.Now;
      StringBuilder sb = new StringBuilder();
      for (int i=0; i < intLimit; i++)
      {
         strSub = i.ToString();
         sb.Append(" ");
         sb.Append(strSub);
      }
      endTime = DateTime.Now;
      elapsedTime = endTime - startTime;
      lblBuild.Text = elapsedTime.ToString();
//      lblBuildString.Text = sb.ToString();
   }

</script>

<html>
   <body>
   <form runat="server">

      <h1>String Concatenation Benchmark</h1>

      Concatenation:  
      <asp:Label
         id="lblConcat"
         runat="server"/>

      <br/>

      <asp:Label
         id="lblConcatString"
         runat="server"/>

      <br/>
      <br/>

      StringBuilder:  
      <asp:Label
         id="lblBuild"
         runat="server"/>

      <br/>

      <asp:Label
         id="lblBuildString"
         runat="server"/>

    </form>
   </body>
</html>

The difference between the two techniques is fairly dramatic: the StringBuilder's Append method is nearly 200 times faster than string concatenation, as shown below:

String Concatenation Benchmark

5. Use server-side controls only when necessary.

ASP.NET introduced a new type of control that is processed server-side, known as Web Server Controls. Since they are typically indicated in code with the following syntax:


<asp:TextBox  id="txtLastName" size="40" runat="server" />

they are also sometimes known as ASP controls. Server-side controls are denoted by the runat attribute, which will always have the value "server."

Classic HTML controls can easily be converted to server-side processing simply by adding the runat attribute, as in the following example:


<input type="text" id="txtLastName" size="40" runat="server" />

Server side processing buys a lot of flexibility, since you can now refer to the control in your program by the name specified in the id attribute, and you can set properties and retrieve values programmatically.

This flexibility comes at a cost, however. Every server control consumes resources on the server. In addition, unless the view state is explicitly disabled either for the control, the page, or the application, the state of the control is contained within the view state's hidden field, and passed over the wire with every postback. This can lead to significant performance degradation.

A good example of this is the use of a table for the alignment of controls on a page. If none of the table elements need to be referred to in the code, use a classic HTML table with no server-side processing. You can still place server controls inside HTML table cells and refer to those server controls in your code. If, however, you need to refer to any of the table elements, such as a specific cell, then the entire table must be a server control.

6. To navigate to a URL without posting the form, use a HyperLink control; to post the form and then navigate, use a LinkButton.

To the Web page visitor, a HyperLink control and a LinkButton control look identical. However, there is a significant difference in functionality.

The HyperLink control immediately navigates to the target URL when the user clicks on the control. The form is not posted to the server.

The LinkButton control first posts the form to the server, then navigates to the URL. If you need to do any server-side processing before going to the target URL, use a LinkButton. On the other hand, if there is no server-side processing necessary, don't waste a round trip and use the HyperLink control.

7. Comment your code.

This tip is not specific to ASP.NET, but rather is just good programming practice. Remember Alzheimer's Law of Programming. If you don't remember it, look at the end of the first tip in this article.

Comments should not only clarify what is going on, but also why. For example, don't just say you are iterating through an array. Say you are iterating through an array to compute a value according to an algorithm, then include the algorithm in the comment unless it is crystal clear from the code. It is often helpful to include a comment block at the beginning of a method that provides an overview of what the method does.

The different languages you may run across in a typical .NET project each have their own commenting syntax. Here is a brief summary:

HTML <!-- the comment -->
JavaScript // the comment
VBScript ' the comment
VB.NET ' the comment
C# // the comment
/* a multiline comment
goes between the two ends */
SQL -- the comment

There is no comment syntax inside the opening and closing tags of a server control. However, the server ignores any attributes it does not recognize, so you can insert comments by using an undefined attribute, as in:


<asp:TextBox  
	id="txtLastName" 
	size="40" 
	comment="This is my comment"
	runat="server" />

Visual Studio .NET makes it easy to comment your source code. Highlight the line(s) to be commented and press Ctrl+K+C to comment the lines. To uncomment, highlight the commented code and press Ctrl+K+U.

In C# projects, you can also enter XML comment sections in your Visual Studio .NET projects using three slashes (///) at the beginning of each line in the section. Within the commented section, you can use the following XML tags to organize your comments:

  • <summary></summary>
  • <remarks></remarks >
  • <param></param>
  • <returns></returns>
  • <newpara></newpara>

To view a formatted report of these XML comments in Visual Studio .NET, go to the Tools menu item, then select Build Comment Web Pages.

8. Trace page execution using the trace methods and trace attribute in the Page directive.

One time-honored technique for debugging a program is to insert output statements at key points in the program. Often, the message will also include the value of important variables. The message can be output to the screen, to a log file, or to a database.

ASP.NET makes this debugging technique even easier with the use of the trace attribute in the Page directive. A Page directive is a line of code at the beginning of an ASPX file that provides direction to the compiler. The Page directive contains one or more attributes, providing the compiler such information as the language being used, the location of the code-behind file, or the name of a class to inherit from.

One of the attributes available in a Page directive is trace, which can have a value of either true or false. Below is a typical Page directive with the trace attribute set true.


<%@ Page language="c#" trace="true" %>

If trace is set to true, the Web page resulting from the ASPX file will show, in addition to the page itself, a great deal of information about the page being displayed. This information is presented in a table arranged in the following sections:

Request Details Provides the Session ID, the time of the request, the type of request, and the status code for the request.
Trace Information Contains the trace log, a chronological listing of the steps in the page life cycle. Custom information can be added to this section.
Control Tree Lists all the controls on the page in a hierarchical manner, including the size in bytes of each control.
Cookies Collection Lists the cookies created by the page.
Headers Collection HTTP headers and their values.
ServerVariables Server environment variables relevant to the page.

The Trace Log, contained in the Trace Information section, is the most useful. It is here that you can insert your own trace statements. There are two methods of the trace class which can insert statements in the Trace log: Trace.Write and Trace.Warn. They are identical except that Trace.Warn statements display in a red font while Trace.Write statements display in a black font. Below is a screen shot of a Trace Log with several Trace.Warn statements:

Trace Information

The most convenient feature about the Trace Log is that you can strew Trace.Write and Trace.Warn statements throughout your code during development and testing, then disable them all with one fell swoop simply by changing the value of the trace attribute in the Page directive when it is time to put the application into production. It is not necessary to remove the trace statements prior to program deployment.

Tracing can also be configured application- or machine-wide, by editing the <trace> tag in the web.config or machine.config files, respectively.

9. Use stored procedures.

Microsoft SQL Server and other modern relational databases use SQL statements to define and process queries. When a SQL statement or set of SQL statements are submitted to the SQL Server, the statements are parsed, a query plan is created and optimized, and the query is executed. This takes time.

A stored procedure is a set of SQL statements that have been pre-parsed and pre-optimized by the query processor, and stored so they are ready for quick execution. Stored procedures, often called sprocs, can be written to accept input parameters, allowing a single sproc to handle a wide range of specific queries.

Because sprocs are parsed in advance, and, more important for complex queries, have their query plans pre-optimized, calling a sproc is much faster than executing the same SQL statements outside of a sproc.

10. Use the .NET command prompt.

The .NET command line utilities are run from the command prompt window. In order for the command to execute however, it must reside in the current directory of the command prompt, or the PATH environment variable must be properly set.

The .NET SDK installs a menu item in the Start menu that opens up a command prompt window with the PATH properly set. To get to this, click on the Start button, then Programs>Microsoft Visual Studio .NET>Visual Studio .NET Tools>Visual Studio .NET Command Prompt.

You may find it convenient to copy the shortcut for this menu item to your desktop by pressing Ctrl+C while dragging the menu item from the menu to the desktop.

Dan Hurwitz is the president of Sterling Solutions, Inc., where for nearly two decades he has been providing contract programming and database development to a wide variety of clients.


Return to the .NET DevCenter.