Software Developer's Resources

Shopping Cart Systems
Mobile Text Marketing Solutions
Online Backup Solutions
ASP.NET Web Development
Skip Navigation Links.

Common Design and Coding Problems in ASP.NET Applications

This article describes the common design and coding problems I discovered in several ASP.NET web applications.

How did I discover these problems? I inherited several ASP.NET web applications over the past several years. My responsibility was to review the web application, locate problems, correct the problems, and create working web applications.

Poorly designed and coded web applications impact clients in several ways:

  • Higher development costs.

    These clients paid two (or more) developers to create the web application. The initial developer made a non-working application. Clients had to locate and pay a second developer to correct the problems created by the first developer.

  • Lost revenue.
  • A web application with many problems can not be put into production. The client is not collecting fees from customers and thus loses revenue.

  • Lost Productivity
  • The client must explain to two (or more) developers how the web application must work. The client can't focus on other business tasks while they are spending time directing additional developers on how to create the web application.

Here are some suggestions on how clients can save money and collect revenues sooner when hiring web developers for their projects.

  • Chunk your project into several small projects.
  • Write carefully thought out descriptions of each feature.
  • Think "Continuous Improvement". Create a basic web site with the minimal features. Put it into production. Add a few features or improve upon the existing features. Put the new version into production. Repeat as needed.

For each problem in this article I:

  • Describe the problem.
  • Give an example of the problem.
  • List the disadvantages caused by the problem.
  • Give a solution.
  • Give an example of the solution.
  • List the value of the solution.

Using Fixed Numerical Indexing to Access Arrays

The code indexes into arrays using fixed numerical indexes.

Bad Example 1 - Stored Procedure Parameters

Insert or update a record with 60 values:

    SqlParameter[] Params;
    	
    Params = new SqlParameter[60];
    Params[0] = new SqlParameter("PropertyId", SqlDbType.Int);
    Params[0].Value = PropertyId;
    	     ...
    Params[59] = new SqlParameter("ZipCode", SqlDbType.VarChar, 20);
    Params[59].Value = ZipCode;        
        
    // Call SqlCommand.ExecuteQuery to insert or update the database.

Bad Example 2 - Reading Data from DataRow

Read a record from the database and get the values from the DataRow:

    DataRow Dr;
    DataTable Dt;
    int PropertyId;
    string ZipCode;
    
    // Select property records from database
    
    Dr = Dt.Rows[0];
    PropertyId = (int)Dr[0];
        ...
    ZipCode = (string)Dr[59];      

Disadvantages

  • Difficult to update code to get new values from arrays.
  • Difficult to update code to put new values into arrays.
  • Difficult to know whether values are copied to the correct variables.

Solution

Use alphabetic keys to index into arrays instead of numerical indices.

Better Example

    DataRow Dr;
    DataTable Dt;
    int PropertyId;
    string ZipCode;
    
    // Select property records from database into DataTable.
    
    PropertyId = (int)Dr["PropertyId"];
        ...
    ZipCode = (string)Dr["ZipCode"];
    

Value

  • Easily update code to get values from or put values into arrays.
  • Higher probability values are copied to correct corresponding variables.

In-Line SQL Statement Composition

The code composes SQL statements in-line by concatenating strings.

Bad Example

Code composes an SQL statement to insert a new record into the database.

    string Sql = "";
    
    Sql = "INSERT INTO Properties (Address,City,State) ";
    Sql += "VALUES ('" + Address + "','" + "','" + City + "','" + State +"')";

Disadvantages

  • Difficult to ensure SQL syntax is correct: Are single quotes balanced?
  • Difficult to add new parameter values and ensure SQL syntax is correct.
  • Difficult to test the SQL statement by itself.
  • Difficult to use SQL statement from multiple areas in the application.
  • Vulnerable to SQL injection attacks. Parameter values can contain malicious SQL when values obtained from web forms.

Solution

The solution is to create a SQL stored procedure to access the database and write code to execute the stored procedure.

Better Example

    SPR_Database DbObj;
    SqlParameter ParamAddress;
    SqlParameter ParamCity;
    SqlParameter ParamState;
    SqlParameter ParamZipCode;
    
    using(DbObj = new SPR_Database())
    {
        DbObj.Command.CommandText = "PropertiesInsert";
        DbObj.Command.CommandType = CommandType.StoredProcedure;
        
        ParamAddress = DbObj.Command.Parameters.Add("@Address", SqlDbType.VarChar, 100);
        ParamAddress.Value = Address;
            ...
        DbObj.Command.ExecuteNonQuery();        
    }

Value

  • Easier to ensure SQL syntax is correct. SQL tools validate SQL syntax.
  • Easier to add new parameter values.
  • Easier to test SQL stored procedures.
  • SQL stored procedures can be used from multiple spots in the application.

Wrong Database Data Types

The database is designed with the wrong data types.

Bad Examples

A boolean true\false values represented with a VARCHAR data type:

    Approved varchar(1)

A record id represented with the wrong numeric data type:

    PropertyId NUMERIC(18,0)

Disadvantages

  • Potential for invalid values to be stored in the database.
  • Potential for invalid conversion between data type at code level and database levels.
  • Consumes unneeded database space.

Solution

Use the correct data type to represent the data.

Better Examples

  • Use BIT instead of VARCHAR data type.
  • Use BIGINT instead of NUMERIC(18,0)

    Approved bit
    PropertyId bigint

Value

  • Faster database performance.
  • Less database space required.
  • Only valid values can be stored in database.
  • Eliminates potential for invalid data type conversions.

Unneccessary Data Conversions

Code converts between boolean values and string "Y" and "N".

Bad Example

Here's code for a property. The get accessor converts the string "Y" or "N" to a boolean, the set accessor converts the input boolean value to a string.

    public bool Approved
	{
	    get
		{
		    bool Status = true;
		    if (m_Approved == "Y") { Status = true; }
		    else if (m_Approved == "N") { Status = false; }
		    return Status;
		}
		set
		{
            if (value == true) { m_Approved = "Y"; }
            else { m_Approved = "N"; }
		}
	 }

Disadvantages

  • Increases potential for invalid values to be stored in the class.
  • Difficult to understand code due to code clutter.

Solution

Be consistent in using same data values.

Better Example

    public bool Approved
	{
	    get
		{
		    return m_Approved;
		}
		
		set
		{
		    m_Approved = value;		
		}
	 }    

Value to This Approach

  • No invalid values stored in class variable.
  • Easier to understand code due to less code clutter.

Replicated Code Blocks

The developer made multiple copies of the same code blocks in multiple in the web project. I have seen the contents of entire web forms replicated: one web form to add a new record, and a second web form (with the same fields) to update the record. The web form contained 50-60 fields.

Disadvantages

  • Difficult to keep all code blocks in sync when making changes.
  • Difficult to test.
  • Obscures code functionality due to code clutter.

Solution

Create a single module, such as, a class, user control, server control, or web form, to contain the code. Use the module as needed throughout the application.

Value

  • Easier to update single module with changes.
  • Can be used in multiple projects.
  • Reduces potential for bugs.
  • Easier to test.
  • Easier to understand code due to less code clutter

Read All The Data Every Time

The code reads all columns for a record every time data is required for any and all tasks such as, display or processing.

Suppose an application has a table with 60 columns. The application read all 60 columns from the database, copied the values into class member variables every time the code needed even a single value.

Disadvantages

  • Slower application performance.
  • Slower database performance.

Solution

Read only the data required for each task in the application.

Create a single class and create a method for each set of data required by each task. Suppose, a table exists to store residential home property information. The application may need different sets of information at different times:

  • Login Data
  • Address Data

Better Example

    public class Property
    {       
        public DataRow AddressRead()
        {
        }
        
        public DataRow LoginRead()
        {
        }
    }

Value

  • Faster application performance.
  • Faster database performance.

In-Line HTML

The code contains dynamically constructed HTML. In some applications I have seen the same code to generate the same HTML replicated in multiple locations in the application.

Bad Example

    string Html = "";
    
    Html = "<div class='Code'>" + "The hungry cow jumped over the moon." + "</div>";

Disadvantages

  • Slow code performance when concatenating strings to build HTML.
  • Generated HTML might be browser incompatible.
  • Generated HTML might have syntax errors.

Solution

Ideas:

  • Use ASP.NET HTML OR ASP.NET Web Controls
  • Sublcass ASP.NET HTML or ASP.NET Web Controls to create a custom control.
  • Create a single custom server control and call as needed in your application.

Value

  • Improved code performance.
  • HTML is browser compatible when using standard ASP.NET controls.
  • Easier to debug browser compatibilities when using a single server custom control.

Embedded CSS

The code contains embedded CSS. In many instances embedded CSS was replicated in many areas of the application.

Disadvantages

  • Developer must update embedded CSS. Client or graphic designer can't update CSS.
  • More time needed to debug CSS related issues due to needing to recompile web project for every change.
  • Difficult to maintain multiple copies of the same embedded CSS in sync across application.

Solution

Move CSS to a separate CSS stylesheet file. Link to the CSS file using the <link /> tag

Better Example

    <link href="SPSC_StyleSheet.css" rel="stylesheet" type="text/css" />

Value

  • Client or graphic designer can update CSS without developer involvement.
  • Client or graphic designer can debug CSS related issues independent of developer.
  • Easier to maintain consistent CSS for whole application.

Storing String Constants

Database tables store string constants.

Bad Example

Suppose the goal of the databaes is to store data related to residential homes: address, property information, such as square footage, etc.

The database was designed to store a U.S. state name string in the property record.

Disadvantages

  • Difficult to maintain a valid list of string constants.
  • Difficult to modify string constants to correct spelling errors, etc.
  • Difficult to populate drop down lists, etc with the correct string contants.
  • Potential for invalid values to be stored in the table.
  • Slow database performance when searching on the string field.

Solution

  • Create a table to hold the set of constant strings.
  • Create a foreign key to the records in the string constants table.
  • Create a database relationship between the tables and keys.
  • Create ASP.NET user or server conrtols to display the string constants for drop down lists, etc.

Better Example

Value

  • Easier to maintain the valid list of string constants.
  • Easy to correct incorrect string constants.
  • Easy to populate drop down lists, etc. with the valid set of string constants.
  • Reduces potential for invalid values to stored in the table.
  • Faster database performance when searching based on the set of string constants.

Multiple Classes Per Source Code File

A single source code file contains two or more classes.

Bad Example

A single file containing two or more class definitions.

    public class Property
    {
        ...
    }
    
    public class Images
    {
        ...
    }

Disadvantages

  • Challenging to locate a class when the file name differs from the class name.
  • Creates code clutter hindering comprehension of the code.

Solution

Put one class per source code file.

Value

  • Easier to lcoate a classes.
  • Less code clutter.

Hard-Coded Text

The code contains hard-coded text. In many instances the same text phrases are replicated in multiple locations in the code.

Disadvantages

  • Client can't change text.
  • Developer involvement required to change text. Increases costs.
  • Difficult to keep the multiple copies of text phrases in sync when making changes.

Solution

Put text in the database:

  • Create a database table for the text.
  • Insert text into the databae.
  • Write a class to retrieve the text from the database using a key.
  • Write a method in the class to display the text phrase.

Create a simple administrative user interface for the client to add and modify text phrases.

Value

  • Client can change text at any time without developer involvement.
  • Ensures same text phrase used consistently throughout application.

Credit Card Data Stored in PlainText in Database

The code accepts credit card number, expiration date, security code, and credit card holders name from the user and stores the information in the database without enciphering the data.

Disadvantages

  • Malicious users can hack into the database and steal credit card data.
  • Security breach can result in loss of reputation for client.

Solutions

  • Seek credit card payment solutions where it is not required to store the credit card data in your database.
  • Encipher the credit card data. Secure the encipher keys.

Value

  • Malicious users can't get the credit card data if it's not stored in your database.
  • Malicious users can't decipher the credit card should they access the database.

Input Data Not Validated

The code does not validate the data or performs poor validation of the data retrieved from web form input controls, such as, TextBoxes, FileUpload, etc.

Bad Examples

Example 1: The user enters an invalid zip code into a TextBox. The code retrieves the value from the TextBox and attempts to compute a latitude and longitude using Google Map services.

Example 2: The code successfully validates a single character for a password.

Disadvantages

  • Invalid data can cause program exceptions.
  • Invalid data can cause downstream data computations to be incorrect.
  • Easier for malicious users can hack into the system (single character password).

Solution

Validate input data using ASP.NET Validator controls, or custom code.

Review validation algorithms to ensure data is correctly validated.

Value

  • Reduces or eliminates potential for program exceptions.
  • Ensures downstream data compurations are correct.
  • Reduces potential for malicious users to hack into the system.

Embedded JavaScript

The ASP.NET C# code contains embedded JavaScript.

Disadvantages:

  • Difficult to test.
  • Difficult to use in multiple locations in the application.

Solutions

Option 1:

  • Put the JavaScript in a separate file.
  • Include the JavaScript in the HTML by using <script src="FileName"></script>

Option 2:

  • Put the JavaScript in a separate file.
  • Code a method to read the JavaScript file and add it to the HTML by calling: Page.ClientScript.RegisterClientScriptBlock().

Value

  • Easier to test.
  • Can be used in multiple locations.

Hard Coded Data

Code contains hard coded data which should be stored in the database.

Disadvantages

  • Difficult to maintain consistent data.
  • Difficult to change data. Must search for all places in code where data resides.

Solution

Create database tables for each set of related data, populate the tables with the data, and remove the data from the source code.

Value

  • Easier to maintain data.
  • Data always consistent.

Master Pages Not Used

The developer replicated the same HTML formatting tags for page layout in many or all web pages for the application.

Disadvantages

  • Difficult to apply page layout and formatting changes consistently across all web pages.
  • Difficult to understand due to code clutter.

Solution

Use ASP.NET Master Pages:

  • Create a master page
  • Edit the master page with the common page elements and page layouts.
  • Apply the master page to all web pages.

Value

  • Easier to update with common layout changes.

No Subclassing

The code did not use subclasses in cases where needed, although web project used Object-Oriented Programming languages, such as, C# or VB.

Disadvantages

  • Additional code required to perform tasks.
  • Obscures code function due to code clutter.

Solution

Create subclasses.

Value

  • Reuse base class variables and methods.
  • Easier to see purpose of code due to reduced code clutter.

Same Data Stored in Multiple Tables

Several database tables contain the same data.

Disadvantages

  • Difficult to maintain data consistency.
  • Extra code required to update multiple instances of the same data. Creates code clutter.

Solution

Create a single database table, migrate the data to the new table, and remove the data from the original tables.

Value

  • Easier to maintain single set of data.
  • Less code clutter, easier to comprehend purpose of code.

Hard-Coded Absolute Urls

The code uses hard-coded absolute urls to redirect to other pages in the application.

Disadvantages

  • Difficult to execute and debug the application in development, beta test, and live environments.
  • Extra development time required to update base urls run application in desired environment.

Solution

Use relative urls.

Value

  • No development time required to update urls based on run environment.
  • Easier to run and execute application in development, beta text, and live environments.

Error Dialog Boxes

System displays error messages in a popup dialog.

Disadvantages

  • User forced to perform extra steps to dismiss dialog box.
  • Difficult for user to see correspondence between errors and related fields.

Solution

Display error messages near the fields which caused the error.

For ASP.NET applications one can use and place Validator controls, such as, RequiredFieldValidator, RegularExpressionValidator, etc. near the data input or data selection controls.

    <asp:TextBox ID="ZipCode" runat="server"></asp:TextBox>
    <asp:RegularExpressionValidator ControlToValidate="ZipCode"
        ErrorMessage="Bad ZipCode"
        ValidationExpression="[0-9]{5}-[0-9]{4}"        
        runat="server"></asp:RegularExpressionValidator>

Value

  • Less steps required of user to see errors.
  • Easy for user to know correspondence between errors and related fields.

User Forced to Re-Enter Data

For a login form: User enters email, clicks on Login button, system displays error message informing user email invalid. User clicks on Forgot Password button\link, system displays a Forgot Password form with an empty email input text box. User is forced to re-enter email.

Disadvantages

  • User must perform additional and unneceesary steps to accomplish a simple task.
  • User can become frustrated.

Solution

Design the login form and code to allow the user to login and request their password.

Value

  • User accomplishes task in fewer steps resulting in less frustration.

Data List Stored in Database

A set of data formatted in a comma-separated list is stored in a VARCHAR field in the database.

Bad Examples

    1,3,5,7,11,13,15
    Alaska, Minnesota, Massachusetts, Wyoming

Disadvantages

  • Potential for code to incorrectly format comma-separated list.
  • Potential for errors when parsing data list.
  • Can't enforce database relationships (if data items are record ids).
  • Slow database search performance if searching performed on data list.

Solutions

The solution is dependent on the specific problem and needs of the application.

One potential solution assuming the data list contains record ids:

  • Create a "link" table between the source and destination tables.
  • Create SQL stored procedures to insert, update, or delete records into or from the "link" table.

Value

  • Ensures only valid data is used.
  • Faster database search performance.

Procedural Programming

Portions of the applications were programmed in a procedural programming paradigm (although in some cases the web projects used an object-oriented language like ASP.NET C# or VB).

Additionally, the procedural code to perform a single function was distributed across several source code files.

Disadvantages

  • Difficult to reuse.
  • Difficult to replace the procedural code with a new improved version.

Solution

Redesign the code into object-oriented programming paradigm.

Value

  • Easier to reuse the oop classes.
  • Easier to improve the code.

Unnecessary Conversions

The code performed unnecessary conversions between data types.

Bad Example

    string Count;
    int Count2;
    
    // Store value in session variable.
    // Note: value stored as integer data type.    
    Session("Count") = 23;
    ...
    
    // Code performs unnecessary conversion to string.
    Count = Session("Count").ToString();
    // Code performs additional conversion to an integer data type.
    Count2 = Convert.ToIn32(Count);
    
    // Code should be:
    Count2 = Session("Count");

Good Example

    Session("Count) = 23;
    ...
    Count = Session("Count");