Top 6 Ways to Improve Your .NET Framework Code

Introduction

As .NET developers, it’s often easy to do something a certain way just because that’s the way we’ve always done it. In a world of constantly changing technology, we should be thinking through every task we perform to ensure that we’re doing it the best way possible. The goal of this article is to point out a few tips on simple things you can do to improve your .NET code, from increasing maintainability and usability, to improving performance.

1. Eliminate Duplicate Code

Duplicate code is a big pet peeve of mine, and it should be one of yours too. Duplicate code is a maintenance nightmare. Nothing is more frustrating than having to make a change to your code, only to realize that the same code is in a hundred different places in your application. Any time you find yourself copying and pasting code from one part of your application to another, you should stop and ask yourself, “Is there a better way I can do this?” Here are some examples of things I do in my applications to reduce code duplication:

  • Do you have a lot of query string parameters that get passed between pages? Create a custom page base with a property that accesses the value in the query string. Even if you only access the query string parameter on one page, put it in a property on the page to make retrieval easier.
  •   public class AdminPageBase : System.Web.UI.Page
      {
          /// <summary>
          /// Id of the Organization in the query string
          /// </summary>
          public int OrganizationId
          {
              get
              {
                  if (!String.IsNullOrEmpty(this.Request.QueryString["ID"]))
                  {
                      int result = 0;
    
                      if (int.TryParse(this.Request.QueryString["ID"], out result))
                      {
                          return result;
                      }
                  }
                  return -1;
              }
          }
      }
    

  • Refactoring applies to user controls, too. If there is markup in your design that you find yourself copying frequently, go ahead and turn it into a user control. Some custom controls will be specific to your application, but you may find that there are controls you can reuse across multiple applications. For example, I’ve found that creating a custom label control that takes an image URL is extremely helpful for displaying standard error/warning messages across my sites. I’ve also created a custom grid control that allows for an “add” row in the footer. Both of these are controls that I’ve used across multiple applications.

  • Another way of refactoring your code is to eliminate any use of inline styles in your markup. Making proper use of a CSS style sheets and skin files will help make your site more consistent and more easily maintainable.

2. Follow Accessibility Standards

Have you tested your website with JavaScript disabled in your browser? Do all of your images have “alt” tags specified? These kinds of things are important when dealing with the accessibility of your site. A lot of company or school computers may have JavaScript disabled and many screen readers for the visually impaired rely on the markup of your website being a certain way. You should spend some time testing your website with different access settings.

3. Implement Proper Error Handling

Error handling is another one of those things that we as developers often leave until the end of development. While it’s nice to assume that all the code we write is flawless, error handling is a must. Too often I’ve seen developers rely on a standard error page set in the web.config (and in some cases, even that is skipped and the standard .NET framework error screen is displayed). To make a truly user friendly application, we should be taking every opportunity possible to provide specific, meaningful error messages to our users in order to increase the possibility that they can fix their own errors. Some rules to follow when doing error handling:

  • Every postback event should have error handling. Button clicks, selected index changed, row click events – they should all be wrapped in a try/catch block and provide meaningful error messages to the user.
  • A standard error page should be set in your web.config in addition to page specific error handling. This should not be your only means of error handling!
  • All errors in the application should be logged to an error log, preferably in your database. The exception, any inner exceptions, the stack trace, the date and time of the error, and, if applicable, the user who caused the error should be captured in the log. This is invaluable as a .NET developer trying to pinpoint the cause of an error that occurred in a production environment.

4. Remember URL Security

One of the first things I do when testing a website is manually modify the URL. Am I able to get to pages in the site that I shouldn’t have access to by changing the URL? Am I able to access records I shouldn’t have access to by changing the ID that is passed in the query string? Always be sure to test your site from the viewpoint of a malicious user and make sure your URLs are secure.

5. Don’t Overuse Viewstate

Its common knowledge that viewstate is used to maintain the state of controls across postbacks. It is stored in a hidden field on the page with an id of “__VIEWSTATE“. Viewstate is turned on by default for every control with a runat=”server” attribute. For pages with a lot of controls and a lot of data, viewstate can get quite large, which can have a negative impact on the performance of your page. The more data that is stored in viewstate, the more data that needs to be sent back and forth to the server with each postback. One common mistake I see made by developers is leaving viewstate turned on for controls where it isn’t necessary. Here are some tips for disabling viewstate on your web forms:

Start with labels. If nothing is changing on the label (visibility, text, style) on a postback, the viewstate can be turned off.

Another trick I like to use is to turn viewstate off on my error and success labels. This not only helps reduce the amount of data stored in viewstate, but it eliminates the need to clear the value from the success or error message labels on every postback.

Because grids frequently have a lot of data in them, turning off viewstate on a grid can have a huge impact on the performance of your page. Take a look at the size of the viewstate controls below. Both are from the exact same page displaying the exact same grid with two columns and 25 rows of data. The first example has viewstate on the grid turned on. The second has viewstate turned off. Big difference, isn’t it? Now imagine if we’re displaying 10 columns and 100 or more records!

  <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTE2MTcyNDI2MjkPZBYCZg9kFgICAw9kFgICBQ9kFgICAQ88KwARAgAPFgQeC18hRGF0YUJvdW5kZx4LXyFJdGVtQ291bnQCGWQBEBYAFgAWABYCZg9kFjQCAQ9kFgRmDw8WAh4EVGV4dAUBMWRkAgEPDxYCHwIFB3ZhbHVlIDFkZAICD2QWBGYPDxYCHwIFATJkZAIBDw8WAh8CBQd2YWx1ZSAyZGQCAw9kFgRmDw8WAh8CBQEzZGQCAQ8PFgIfAgUHdmFsdWUgM2RkAgQPZBYEZg8PFgIfAgUBNGRkAgEPDxYCHwIFB3ZhbHVlIDRkZAIFD2QWBGYPDxYCHwIFATVkZAIBDw8WAh8CBQd2YWx1ZSA1ZGQCBg9kFgRmDw8WAh8CBQExZGQCAQ8PFgIfAgUHdmFsdWUgMWRkAgcPZBYEZg8PFgIfAgUBMmRkAgEPDxYCHwIFB3ZhbHVlIDJkZAIID2QWBGYPDxYCHwIFATNkZAIBDw8WAh8CBQd2YWx1ZSAzZGQCCQ9kFgRmDw8WAh8CBQE0ZGQCAQ8PFgIfAgUHdmFsdWUgNGRkAgoPZBYEZg8PFgIfAgUBNWRkAgEPDxYCHwIFB3ZhbHVlIDVkZAILD2QWBGYPDxYCHwIFATFkZAIBDw8WAh8CBQd2YWx1ZSAxZGQCDA9kFgRmDw8WAh8CBQEyZGQCAQ8PFgIfAgUHdmFsdWUgMmRkAg0PZBYEZg8PFgIfAgUBM2RkAgEPDxYCHwIFB3ZhbHVlIDNkZAIOD2QWBGYPDxYCHwIFATRkZAIBDw8WAh8CBQd2YWx1ZSA0ZGQCDw9kFgRmDw8WAh8CBQE1ZGQCAQ8PFgIfAgUHdmFsdWUgNWRkAhAPZBYEZg8PFgIfAgUBMWRkAgEPDxYCHwIFB3ZhbHVlIDFkZAIRD2QWBGYPDxYCHwIFATJkZAIBDw8WAh8CBQd2YWx1ZSAyZGQCEg9kFgRmDw8WAh8CBQEzZGQCAQ8PFgIfAgUHdmFsdWUgM2RkAhMPZBYEZg8PFgIfAgUBNGRkAgEPDxYCHwIFB3ZhbHVlIDRkZAIUD2QWBGYPDxYCHwIFATVkZAIBDw8WAh8CBQd2YWx1ZSA1ZGQCFQ9kFgRmDw8WAh8CBQExZGQCAQ8PFgIfAgUHdmFsdWUgMWRkAhYPZBYEZg8PFgIfAgUBMmRkAgEPDxYCHwIFB3ZhbHVlIDJkZAIXD2QWBGYPDxYCHwIFATNkZAIBDw8WAh8CBQd2YWx1ZSAzZGQCGA9kFgRmDw8WAh8CBQE0ZGQCAQ8PFgIfAgUHdmFsdWUgNGRkAhkPZBYEZg8PFgIfAgUBNWRkAgEPDxYCHwIFB3ZhbHVlIDVkZAIaDw8WAh4HVmlzaWJsZWhkZBgBBRhjdGwwMCRNYWluQ29udGVudCRndkdyaWQPPCsADAEIAgFk+63YgFL7ES3E/2JFgzF0iZug79alSUYBo5I2V7w40B8=" />

Example 1: GridView viewstate enabled

  <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTE2MTcyNDI2MjlkGAEFGGN0bDAwJE1haW5Db250ZW50JGd2R3JpZA88KwAMAQgCAWSY1rDMoV+AqStXcDtv6oIn3zTSLwNXWIdtkkz/2PENOg==" />

Example 2: GridView viewstate disabled

6. Proper Object Disposal

All object that implement the IDisposable interface need to be disposed of after their use to avoid eating up memory in your application. Probably the most common objects that are used that need to be disposed of are database connection objects (e.g. System.Data.Common.DbCommand, System.Data.Common.DbConnection, etc.). Most .NET developers know this. What you may not know is that the “using” statement is a quick and easy way to ensure proper object disposal. Basically, the code block:

  SqlConnection conn;

  try
  {
  conn = new SqlConnection();
  conn.Open();

  // Code to execute query
  }
  finally
  {
  if (conn != null)
  conn.Dispose();
  }

Is the same as the following code block:

  using (SqlConnection conn = new SqlConnection())
  {
  conn.Open();

  // Code to execute query
  }

The following is a brief list of some commonly used classes that implement the IDisposable interface and should be used with using statements:

  • System.Data.Common.DbCommand
  • System.Data.Common.DbConnection
  • System.Data.Common.DbDataReader
  • System.Data.Common.DbTransaction
  • System.Data.Linq.SqlClient.SqlProvider
  • System.Data.OleDb.OleDbCommand
  • System.Data.OleDb.OleDbConnection
  • System.Data.SqlClient.SqlDataReader
  • System.Drawing.Brush
  • System.Drawing.Font
  • System.Drawing.Graphics
  • System.Drawing.Image
  • System.IO.BinaryReader
  • System.IO.BinaryWriter
  • System.IO.Stream
  • System.IO.StreamReader
  • System.IO.StreamWriter
  • System.IO.TextReader
  • System.IO.TextWriter
  • System.Net.Mail.MailMessage
  • System.Threading.Timer
  • System.Web.UI.Control
  • System.Xml.XmlReader
  • System.Xml.XmlWriter

One more tip: You can declare multiple objects within a single using statement. However, the objects must be of the same type, as seen here:

  using (MailMessage mail1 = new MailMessage(),
                     mail2 = new MailMessage())
  {
  // Use mail1 and mail2
  }

Conclusion

These six tips are simple things you can do to improve your .NET code. Remember – “because I’ve always done it that way” is not a good reason to do something! It’s always good to take a few minutes and really think about what it is you’re trying to do and the best way to accomplish it.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read