Three Ways to Catch Exceptions in ASP .NET

Before we get on with the article, a couple of quick announcements. Regular readers of this site know well my tendency to put this site through an obnoxious number of redesigns. Sometimes I feel like I'm in a never-ending design cycle, because I'm always tweaking something here or adding something there. Anyway, I once again found myself twitching to do a redesign. I hesitate to say that I got tired of the old ( well, current, as of this entry ) theme, because I still like it; however, it most definitely grew old. So: look for the new design soon — like over the weekend; definitely over next week. :-)

Moving on.

Catching Exceptions in a Method

public void DownloadPdf(string path)
{
 try
 {
  System.IO.StreamReader reader = System.IO.File.OpenText(path);
 }

 catch (System.UnauthorizedAccessException ex)
 {
  // Hey, you don't have access to the file!
 }

 catch (System.IO.FileNotFoundException ex)
 {
  // Hey, the file doesn't exist
 }

 catch (Exception ex)
 {
  // Something bad happened
 }
}

Catching Exceptions at the Page Level

protected override void OnError(EventArgs e)
{
 Exception exception = HttpContext.Current.Server.GetLastError();

 // Inform the user about the exception, log it, and do whatever 
 // else you want to do here.
}

Catching Exceptions at the Application Level

// In global.asax
protected void Application_Error(object sender, EventArgs e)
{
 Exception ex = HttpContext.Current.Server.GetLastError();

 // Do whatever with the exception here.
}

You might notice that catching exceptions at the application level is remarkably similar to catching them at the page level. This is good — one less thing for us to have to remember. :-)

Clearing Errors

What if you want to have your application continue on its merry way, not stop dead in its tracks because of the exception? For example, suppose the user is trying to upload a file and your application throws an exception because the file is too big. It would be nice if your application lets the user to continue working instead of taking him to the jarringly-ugly yellow page of death error page?

This is what happens when you catch an exception (aka, method 1), so you don't need to do anything special. However, it's a pain to have to wrap every single method in a try...catch block. The way to clear exceptions/errors with the other two methods is with the Server class' handy ClearError method:

 // In global.asax
protected void Application_Error(object sender, EventArgs e)
{
 Exception ex = HttpContext.Current.Server.GetLastError();

 // Do whatever with the exception here.

 HttpContext.Current.Server.ClearError();
}

Conclusion

You should, at some point, trap all exceptions that occur in your application. At the very least, you should redirect the user to a custom error page. Not only are the default error pages produced by ASP .NET horrendously ugly, they're usually unhelpful to the end-user. Also, they reveal information about your code, which is bad from a security-viewpoint. ASP .NET provides 3 very easy ways to trap errors in an application.

My favorite method — well, my second favorite method — of catching exceptions is using the Global.asax's Application_Error method. ( My favorite way is to use HttpModules, which I'm going to talk about in a future article. )

Commenting Out Server Controls in ASP .NET

This is something I seem to be doing an awful as of late. I start out with some control (say a GridView), then switch to some other control (say a Repeater), but I don't want to delete the GridView control until I get the Repeater control working.

You might have tried commenting out the control the HTML way — i.e., <!--...--> — and you probably found out that ASP .NET engine still parses it. Until recently, I was dealing with this the hard way: cutting & pasting the control into Notepad.

No longer.

Enter Server Comments

Namely:

<%--

 <asp:GridView ID="ProductsGridView" runat="server" DataSource="ProductsDataSource">
 </asp:GridView>

--%>

ASP .NET will ignore everything within a server comment block.

Creating Charts in ASP .NET with Office Web Components

In this article, we’re going to learn how to create the chart shown above on-the-fly using ASP .NET and Microsoft Office Web Components.###Step 1: Add a Reference to Microsoft Office Web Components to the Project

The very first thing to do to use MS Office to create eye-catching charts is to add a reference to the Microsoft Office Web Components dll. So go ahead and create a brand new web project imaginatively called “OfficeWebComponents.” MS Office means COM, so when you go to add a reference, you need to go over to the COM tab. Scroll down until you find the right dll, select it, and click OK.

If you have Office running on the machine, then you probably have this .dll already installed. If you don’t, you will have to get it from Microsoft.

Step 2: Write the Code

Don’t forget to add using OWC11; to your code-behind.

Before I explain it, here’s the code:

public partial class _Default :
 System.Web.UI.Page
{
 protected void Page_Load(object sender,
  EventArgs e)
 {
  string[] chartCategories = new string[]
  {
   “Luke Skywalker”,
   “Mara Jade”,
   “Leia Organa Solo”,
   “Mace Windu”,
   “Han Solo”,
   “Anakin Skywalker”,
   “Depa Billaba”,
   “Yoda”
  };

  string[] chartValues = new string[]
  {
   “5″,
   “-50″,
   “3.5″,
   “30″,
   “5″,
   “-20″,
   “20″,
   “0″
  };

  //The charting component wants its categories and
  // deliminated values tab.
  string chartCatsAsString = String.Join(“t”, chartCategories);
  string chartValuesAsString = String.Join(“t”, chartValues);

  //Create the charting workspace
  OWC11.ChartSpaceClass chartSpace = new OWC11.ChartSpaceClass();

  //Create the chart itself 
  OWC11.ChChart theChart = chartSpace.Charts.Add(0);

  //Set the type of the chart
  theChart.Type = OWC11.ChartChartTypeEnum.chChartTypeColumnClustered;

  //Add the chart’s title 
  theChart.HasTitle = true;
  theChart.Title.Caption = "Indecipherable Star Wars Graph";

  //Populate the indecipherable data
  theChart.SeriesCollection.Add(0);

  //Add the categories
  theChart.SeriesCollection[0].SetData(
   OWC11.ChartDimensionsEnum.chDimCategories,
   (int)OWC11.ChartSpecial.DataSourcesEnum.chDataLiteral,
   chartCatsAsString);

  //Add the values
  theChart.SeriesCollection[0].SetData(
   OWC11.ChartDimensionsEnum.chDimValues,
   (int)OWC11.ChartSpecial.DataSourcesEnum..chDataLiteral,
   chartValuesAsString);
   //Show the chart to the client as a GIF image (400×400)

  Response.ContentType = “image/gif”;
  Response.BinaryWrite((byte[])chartSpace.GetPicture(“gif”, 400, 400));
  Response.End();
 }
}

The code is actually pretty-self explanatory (with my comments at least ;-) ). Rather than bore you by going through the same code again, here’s some information that’s not in the code:

  • You add the chart’s legend the same way you add the title: you set the HasLegend property to true and then set the legend.

  • There are a number of ways to display your chart — everything from pie-graphs to scatter-plots.

  • Your category names and values can’t have any commas in them — the charting component seems to deliminate the string at commas as well as tabs.

  • You can save the chart as an image, too; you aren’t limited to sending the image back to the browser.

  • If you have fewer or more categories than values, you don’t get an error — the chart gets rendered with the extra category/value.

Real Life Uses

In real life, we’re obviously not going to have hard-coded categories and values in your code-behind. We’re probably going to get them from the database. This works just fine. For example, suppose you want to figure out how much time you spent each day working on a certain project. These numbers might be stored in a database or an XML file. All you do is simply read the numbers into a values array, and the days into a categories array; join them into a string just like we did in the example, and then go on from there.

1 of 1 pages

On the Side