Tuesday, June 27, 2006

Error Handling in ASP.NET Web Applications

Error handling is very important for any serious application. It is very crucial that the application is capable of detecting the errors and take corrective measures to the maximum possible extend. If the error situation is beyond the control of the application, it should report the situation to the user/administrator so that an external action can be taken.

There are 3 ways to handle exceptions in an ASP.NET web application.

1. Structured Exception Handling

2. Error Events

3. Custom Error Pages

Structured Exception Handling

The most popular error handling is Structured Exception Handling (SEH). Most of us are familiar with it in the form of try..catch blocks. All of us use SEH a lot in whatever application that we are working on. The primary focus of SEH is to make sure that a block of code is executed correctly, and if an exception takes place, we have another piece of code which can take care of the exception and take some corrective measures if possible.

SEH is used to protect the application from an exceptional situation where something unexpected happens. For example the application tries to connect to a database server and the server is not available. It is an exceptional situation or an exception :-). If such a case happens the developer can handle the situation in the catch block and take the necessary action. I have seen smart developers making use of SEH for the application logic too. for example, assume that the developer needs to open a file and display the content. Ideally he needs to check if the file exists first and then if it exists open it as follows. (This kind of programming is called DEFENSIVE Programming).

If file exists   

      work with the file

else   

      take action

end if

But the developer can simply use a try..catch block to open the file without even checking if the file exists as

try   

     just work with the file

catch

     file-does-not-exist-exception   

     take action

end try

The above approach reduces the complexity of checking for the existing of the file etc. However it adds some overhead to the system. Generating and handling an exception takes some system resources. I have also seen people using SEH to branch the code execution to a specific upper function block, from inside a series of complex nested functions.

For example function a calls b and b calls c and c calls d and d calls e and if the developer wants to transfer control to a specific location in any of the parent methods, he or she can make use of SEH. SEH is mostly used for procedure/function level error handling. Any code which access external resources like database connections, files/folders, URLs should always be inside try..catch blocks because they are most vulnerable for exceptions.

I have experienced a lot of trouble with combo boxes too and hence would recommend that any action that you do on a combo box should be inside try/catch blocks. Another area where you might consider is working with a dataaset where a null value can cause an exception.

Error events

Most of the times we will be able to put the code into try..catch blocks. But exceptions occurs in exceptional situations. There might be several cases when we would not be able to fore-see that a given block code is vulnerable to a specific exception.

For example,

 dim CustomerName as string = new string("jacob")

The above statement is not a candidate for an error. No one would expect that the above statement can generate an error. But what if the system memory is full? The system is not able to allocate memory for that variable and it will throw an exception. Is it practical to put every line of code in try..catch blocks and catch every possible exception with every line of code? Of course not.

The best idea is to use Error Events of ASP.NET to handle such exceptions. Error events can be used to catch exceptions which are not handled with SEH. Asp.net provides three events to handle error conditions.

a. page_error

b. global_error

c. application_error

You can write excpetion handling code in page_error to handle any un-handled exceptions that occur inside your page. similarly global_error and application_error can be used for application-wide error handling. From within the error event (page_error, global_error or application_error) you need to find the exception which occured. Server.GetLastError() can be used to retrieve the exception which triggered the error. After you have processed the error, you should call Server.ClearError() so that the further exception processing/handlers are not called.

Custom Error Pages

Yet another way you can handle errors in ASP.NET Web applications is by using Custom Error pages. When an exception occurs you can redirect the user to a customized page which explains the error condition or just give a friendly note to the user. The scope of Custom error page is very much large that it can even detect errors which are not related to the web application. For example, if your web application is down, still you can instruct IIS to show the user a specific page.

Custom error pages can be configured in 3 different ways.

1. Configure the custom error page with IIS

2. Configure the custom error page with web.config

3. Configure the custom error page declaratively in each web form

 

Configuring a custom error page with IIS

You can configure a custom error page with IIS by opening the properties window of your application. Custom error pages in IIS work based on HTTP response codes. you can define a custom page for each HTTP error that you need to handle. The question "which error code should I handle" largely depends on your application. However, I think the following HTTP response codes may be handled in a normal web application. HTTP 401 - Unauthorized HTTP 404 - Page Not Found HTTP 408 - Request Timeout HTTP 500 - Internal Server Error HTTP 503 - Server Not Available

Configuring Custom Error Pages in Web.Config

The section if web.config can be used to configure error pages. The following example shows a typical example.

<customerrors defaultredirect="Error.aspx" mode="on">   

     <error redirect="PageNotFound.aspx" statuscode="404" />   

     <error redirect="InternalServerErr.aspx" statuscode="500" />

</customerrors>

Note: Custom error handling using web.config is applicable to ASP.NET resources only. For example, if a "page not found" error occurs with an aspx file, your custom error page will be displayed. However if a "page not found" error occurs for an html file, your application's error handler page will not be launched. To handle situations external to the web application, the setting needs to be configured with IIS.

Page Level Error Configuration

The error configuration on web.config has application wide scope. However, it is possible to configure the error pages for a given web form. You can specify error pages declaratively on your web form as shown in the following example.

<%@ page language="vb" AutoEventWireup="false" codebehind="pagename.aspx.vb" inherits="projectname.pagename" errorPage="Error.aspx" %>

Setting on the web page supersedes the configuration setting on the web.config. In the above example, if an error occurs inside the above page (pagename.aspx) the user will be taken to "error.aspx" which might contain the details of the page. You can use Server.GetLastError() to identify the exception and can display an appropriate message to the user.

Hope this helps

Monday, June 26, 2006

SQL Server Code Name

Most of you might be aware of the microsoft style of code-naming each product. SQL Server 2005 was code named 'Yukon'. The SQL Server team has completed 17 years this year. Quite admirable! The next version of SQL Server is code named "Katmai"

Sunday, June 18, 2006

SQL Server 2005 - Pivot Query

I suppose most of us might have come across the following situation several times in the past. Let us say for example we need a result set as following

 

 

from a table which has data as follows.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

This essentially means the task is to generate a tabular result set from the rows that we have. With SQL Server 2000, most of us might have used #TEMP tables where we update the data temporarily and SELECTED from. Another option that most of the developers might have used with SQL Server 2000 is the CASE statement. In the example above, you can use a series of 12 CASE statements which can take for each column.

SQL Server 2005 has a handy PIVOT operator which can help us with the above task. The PIVOT clause generates a resultset as shown in the example above. For the purpose of this example, let us create a table as follows.

 

CREATE TABLE invoice (

InvoiceNumber VARCHAR(20),

invoiceDate DATETIME,

InvoiceAmount MONEY )

The above SQL statement creates a table for the purpose of this example. Now let us insert some data into it.

 

INSERT INTO invoice

SELECT 'INV001', '2005-01-01', 100 UNION

SELECT 'INV002', '2005-02-01', 40 UNION

SELECT 'INV003', '2005-03-01', 60 UNION

SELECT 'INV004', '2005-03-10', 15 UNION

SELECT 'INV005', '2005-04-01', 50 UNION

SELECT 'INV006', '2005-05-01', 77 UNION

SELECT 'INV007', '2005-06-01', 12 UNION

SELECT 'INV008', '2005-06-05', 56 UNION

SELECT 'INV009', '2005-07-01', 34 UNION

SELECT 'INV010', '2005-08-01', 76 UNION

SELECT 'INV011', '2005-09-01', 24 UNION

SELECT 'INV012', '2005-09-20', 10 UNION

SELECT 'INV013', '2005-10-01', 15 UNION

SELECT 'INV014', '2005-11-01', 40 UNION

SELECT 'INV015', '2005-11-15', 21 UNION

SELECT 'INV016', '2005-12-01', 17 UNION

SELECT 'INV017', '2006-01-01', 34 UNION

SELECT 'INV018', '2006-02-01', 24 UNION

SELECT 'INV019', '2006-03-01', 56 UNION

SELECT 'INV020', '2006-03-10', 43 UNION

SELECT 'INV021', '2006-04-01', 24 UNION

SELECT 'INV022', '2006-05-01', 11 UNION

SELECT 'INV023', '2006-06-01', 6 UNION

SELECT 'INV024', '2006-06-05', 13

 

Let us create the PIVOT query now which will return a result set as per what we needed.

 

SELECT *

FROM (SELECT year(invoiceDate) as [year], left(datename(month,invoicedate),3)as [month], InvoiceAmount as Amount FROM Invoice) as s

PIVOT

(

SUM(Amount)

FOR [month]

IN (jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec)

)

AS p

 

The above query generates a result set that we needed. Let me explain the structure of the query. The first part of the query

 

SELECT *

FROM (SELECT year(invoiceDate) as [year], left(datename(month,invoicedate),3)as [month], InvoiceAmount as Amount FROM Invoice) as s The first part of the query generates a subtable (view) as per the following.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

The second part of the query generates a PIVOT table from the above result set.

 

SELECT *

FROM (SELECT year(invoiceDate) as [year], left(datename(month,invoicedate),3)as [month], InvoiceAmount as Amount FROM Invoice) as s

PIVOT

(

SUM(Amount)

FOR [month]

IN (jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec)

)

AS p

 

The above query returns a result set as follows.

 

 

Hope this helps! If you found this useful or have a question, please post a comnment to let me know about it.

Saturday, June 17, 2006

Rename a SQL Server 2000 datatabase

I was looking for a quick way to rename a SQL SERVER 2000 database I found the information handy. EXEC sp_dboption 'OldDbName', 'Single User', 'TRUE' EXEC sp_renamedb 'OldDbName', 'NewDbName' EXEC sp_dboption 'NewDbName', 'Single User', 'FALSE' Thankx to Jason Fisher. His short artcile has explanation for this code.

MSN is hiring human search engines!

"MSN is hiring human search engines!". I think this is the best i can describe about it.
Surprised? mee too.

We had been seeing that in the last 1 year MSN had been trying so hard to keep their shares in search business. However we see that every month their search traffic kept going down and down. We also see that microsoft did all the best it can do from hiring the best people to trying to alter its search business strategy. But nothing really helped.

What next? Hire a few "fast typists" and sit them in a backoffice and fire search manually (into Google???) and send the result back to user?

Look at the MSN hiring page under section Hand crafted Results. It says ".... When all else fails, and the ranking algorithms do not pass the confidence threshold, we fall back to delivering handcrafted results. Working on a team of approximately 132 other handcrafters in 26 worldwide markets, you will receive a user query, use all the available search engines to quickly scour the web for results, pick the top 10 results for this query, and send it on to the user ...."

It looked odd at the first glance. But the more and more I thought about it, I see it is an example of an elegent management. When things go wrong, it is very important that a management can take the right decision to keep things going. The result is important. The means does not matter (atleast in this business).

I am wondering, if this approach succeeds, MSN might hire 1 million people to sit at the back office and serve all the user queries.

But if the back office employees are busy i might get a message "All our search officers are serving other customers. Please try after some time by clicking the "refresh" button of your browser. If you are in a hurry, please try at google" :-)

And may be, after a few quarters, the market of search officers (typists) might increase. Microsoft will add a new certification - Microsoft Certified Search Officer or Microsoft Certified Typists.

I am going to improve my typing speed. Are you? :-)

The best domain host is the one that takes cares of everything from domain name registration to hosting service to web site design. Once done with cheap hosting , one can proceed about search engine marketing and other features like internet telephones.

Friday, June 16, 2006

Somasegar's blog on Dot Net 3.0

I just saw Somasegar's blog on Dot Net 3.0 and he has mentioned that the change is "Only in the name". He has also mentioned that it has to do with "branding" and "reducing confusion" about the developer tools. There is a clear statement saying that there will be no changes in the technologies being shipped as part of the package.

Dot Net 3.0

I was much excited when I heard the announcement about Dotnet 3.0. Microsoft showed a lot of magic and facinated everyone including me and you, with the release of DotNet 2.0. So I had been expecting much fun when I started looking deep into DotNet 3.0. When I had a closer look, I saw that it is "Old beer in new bottle". There is nothing REALLY new in Dot Net 3.0. No improvements in framework, CLR. It is just a packaging magic, where WinFx was added to the PACKAGE of Dotnet and it became 3.0 Dotnet 3.0 includes the following.
  • 2.0 CLR
  • 2.0 Base Class Library
  • ADO.NET 2.0, ASP.NET 2.0, Windows Forms 2.0
  • VB 8.0 and C# 2.0
These are the ingrediants we already have. In the past several months most of us would have been working on all these stuff. There is no change in CLR, No enhancements to the Base Class Library, No enhancements in ASP.NET or ADO.net. Now what is new?

Here are the new sweets

  • Windows Communication Foundation (WCF)
  • Windows Presentation Foundation (WPF)
  • Windows Workflow Foundation (WinWF)
  • Windows CardSpace

But the question remains unanswered. Are these really new? These are the sweets we have already tasted. So is it just a re-packing? How is this re-packing going to help me as a developer? Does it really matters to have all these packed into a single gift pack?

I dont mind having my cofee and biscuits in two different packs. I am happy as long as i get them both. Well, if u serve me in a sigle pack, thats fine..I am not excited.

Tuesday, June 13, 2006

Schedule an SSIS package

If you have ever tried to create an SSIS package and tried to schedule it with SQL Server 2005 Jobs, I assume, u must have came across an error which says the job could not be executed. It happened to me too. I did not spent time on troubleshooting it due to the tough time line I had. I used windows task scheduler to run the SSIS package as a workaround and thought of looking into it on a later time. Luckily, I just saw a codeproject article which explains how to fix the problem. The job fails because of the security checks that SQL server 2005 does before executing the package. The above article explains the details. Hope this helps!

Sunday, June 11, 2006

Another IIS error

This weekend I came across another IIS issue. I had noticed that my default website showed a red icon indicating an error but never got a chance to see what is happening. This weekend, I had to configure a website and hence had to sit down and see what is going wrong with my IIS. I saw the default website does not start. When i try to start it, IIS throws an error message "Unexpected error 0x8ffe2740 occurred" My first instinct was to check the path of the default website. But i saw that the default directory (home directory) of the default website is c:\inetpub\wwwroot and the folder exists. So there is no chance that there should be a folder error. As many web developers would do, the next thing i did to correct the problem was to uninstall IIS and reinstall it. I was pretty sure that a reinstallation of IIS will fix my problem. Atleast, in the past, many a times when i faced problems with IIS a reinstallation had helped. So I uninstalled IIS and reinstalled it. I was surprised when I went to IIS manager and found that the default website still could not start. When i try to start it, I got the same error. So frustrating. Isn't it? I did a quick search in google with the error information and came acrosss an MSDN knowledge base article which said that the problem is caused when IIS is not able to open port 80 on the host machine. Ah! that makes sense. Some other application on my machine is using port 80. But who is it? Is it a virus? There is no chance that I have installed an application which might be using port 80. If that is the case, I must make sure if the port is infact used by some one or something else is making my IIS sick. Well, the best friend who can help you to check status of open ports is the old DOS utility netstat. I ran netstat and found that my port 80 is infact used by some one else. Amazing!!! Ok, but who is the culprit? I looked into the task manager and did not find any process which I could suspect. I checked the help documentation of netstat and found that it supports a switch "-b" which would give the name of the process which is using a given port. Thats really interesting! I saw that SQL Server is using 80 port. Then i remember that I had configured SQL Server 2005 Web Services on my machine a few days back. Btw: SQL Server 2005 Web Services are really great stuff that you should look at. I will post a few pieces of interesting information about it shortly. Back to IIS. I would suggest that the first thing we need to do when we have an issue with IIS is to have a quick google search about the problem. Most of the times, it might be far more productive rather than doing an uninstallation and reinstallation of IIS as the first resort.