8/12/11

throw and throw ex

There are some things in life which come back to bite you in the face(haha...) if you do not pay enough attention to them. In my case one such thing was NOT knowing the difference between throw and throw ex when dealing with exceptions in C#(other languages probably do the same). I didnt know that the stack trace was going to be different depending what whether I did a throw or a throw ex and as a result I always ended up looking up in the wrong places whenever there were exceptions deep inside the call stack.Let me give you an example of what I am talking:

Look at the code below. There are three classes Level 1, Level 2, Level 3. Level makes a call to method HelloLevel2()  in Level2 which in turn makes a call to a method HelloLevel3() in Level 3. The method in Level 3 throws an exception.Pay attention to the text in Red.

public partial class Level1 : System.Web.UI.Page
    {        
        protected void Page_Load(object sender, EventArgs e)
        {            
            Level2 objlevel2 = new Level2();
            objlevel2.HelloLevel2();

        }
    }
 public class Level2
    {
        public void HelloLevel2()
        {
            try
            {
                int x = 10;
                Level3 objlevel3 = new Level3();
                objlevel3.HelloLevel3();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
public class Level3
    {
        public void HelloLevel3()
        {
            try
            {                
                throw new Exception("Oops....Something got messed up here");
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }
    }

If you look at the stack trace, this is how it looks. If you notice the text in Red you will notice that even though the error occured in HelloLevel3() there is no indication of that. This is happening because the method HelloLevel2() is doing a throw ex inside it's catch block instead of doing a  throw



[Exception: Oops....Something got messed up here]
   WebApplication1.Level2.HelloLevel2() in C:\VisualStudioProjects\WebApplication1\WebApplication1\Level2.cs:20
   WebApplication1._Default.Page_Load(Object sender, EventArgs e) in C:\VisualStudioProjects\WebApplication1\WebApplication1\Default.aspx.cs:29
   System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +14
   System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +35
   System.Web.UI.Control.OnLoad(EventArgs e) +91
   System.Web.UI.Control.LoadRecursive() +74
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2207

Now, as shown below, I have modified the code in HelloLevel2() to as shown below

 public class Level2
    {
        public void HelloLevel2()
        {
            try
            {
                int x = 10;
                Level3 objlevel3 = new Level3();
                objlevel3.HelloLevel3();
            }
            catch (Exception ex)
            {
                throw;
            }
        }
    }

If we run the application,the stack now looks as shown below:

[Exception: Oops....Something got messed up here]
WebApplication1.Level3.HelloLevel3() in C:\VisualStudioProjects\WebApplication1\WebApplication1\Level3.cs:18

WebApplication1.Level2.HelloLevel2() in C:\VisualStudioProjects\WebApplication1\WebApplication1\Level2.cs:20
WebApplication1._Default.Page_Load(Object sender, EventArgs e) in C:\VisualStudioProjects\WebApplication1\WebApplication1\Default.aspx.cs:29
System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +14
System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +35
System.Web.UI.Control.OnLoad(EventArgs e) +91
System.Web.UI.Control.LoadRecursive() +74
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2207

As you can see it tells you that the exception actually occured in HelloLevel3(). This information is extremely useful and can save hours of troubleshooting in the wrong direction.

Hope this helps! Peace.

3/9/11

Address Verification Software

Last month, I was working on an Order processing application in which the customers had to provide their shipping addresses as a part of the final step. My boss mentioned that prior to shipping, these addresses had to be verified to ensure they were valid deliverable addresses.

My initial thoughts were "Verify addresses? really? How do you do that?".I actually found the idea pretty amusing. Ignorance is bliss I guess.

As I started researching I realized that inaccurate addresses posed a big problem for businesses, especially those that rely on mailings for their sales. Companies that did not have an address verification solution in place were losing millions of dollars in postage, lost merchandise, lost invoices and all the additional time spent by employees in double checking all existing procedures to ensure accuracy. As a result this had opened up a big market for address verification software. A number of companies of varying sizes and shapes offer this software. My next task was to find the one that best suited us.

I poured over a number of "How To" guides on choosing address verification software and also spent a considerable amount of time reading the websites of the various companies suggested in those guides. Finally I narrowed down my choices to the following five companies: 
  • MelissaData
  • Intelligent Search Technology
  • QAS
  • USPS
  • Sartoris Software  
I called each of these companies and spoke to their sales people. I noted down the various options provided by each and also the cost associated with each option. Most of the Companies except USPS offered two options:
  • Hosting the software in-house
    •  You get an installation CD that contains the API and all the addresses. You also get a list of updated addresses every two months  
  • Accessing the software via web services 
    • You pass the address to their web service that will perform the validation and return the results. This option was not offered by USPS. 
    • This option is a lot cheaper compared to the first option.  
In the end we decided to go with the web services option provided by Intelligent Search Technology. They had a good API that satisfied our requirements and the cost was very affordable. Their web services were secure (https based) and used a 128 bit algorithm to encrypt the incoming and outgoing data. I created a proxy and tested their API quite extensively and so far the address verification has been pretty consistent and accurate.

Overall, It has been an amusing and enlightening experience and I hope this information proves useful to people out there looking for address verification software.

3/8/11

Programmer Keyboards



Regular Programmer
Real Programmer

Really Real Programmer

12/11/10

Authentication Issues with WebHttpBinding in WCF 3.5

If you plan to expose your WCF Services via HTTP requests instead of SOAP messages, you will need to use WebHttpBinding to configure your endpoints. When you use do this and host your services in IIS 7.0, you might get the following error:

IIS Specified authentication schemes 'IntegratedWindowsAuthentication,Anonymous'
but the binding only supports specification of exactly one authentication scheme. Valid authentication schemes are Digest, Negotiate, NTLM, Basic, or Anonymous. Change the IIS settings so that only a single authentication scheme is used.

This happens if your services are inside a web application that is configured to use Anonymous as well as Integrated Windows Authentication in IIS. To get around this issue, assuming all your services are in one folder under your application root, select that folder and in the Authentication options,uncheck one of the Authentication options depending on your need. This should fix the problem.

11/14/10

SQL Server 2005 Full-Text Search : Data population failure

After creating the Full-Text Catalogs and Indexes on the SQL Server, I ran a script to populate the indexes. Since population takes a while, especially if the database is large, I decided to check on the status periodically via the FullTextCatalogProperty function in SQL Server. 

One of the properties returned by the function is the PopulationStatus property which has one of the following values:
0 = Idle
1 = Full population in progress
2 = Paused
3 = Throttled
4 = Recovering
5 = Shutdown
6 = Incremental population in progress
7 = Building index
8 = Disk is full. Paused.
9 = Change tracking

In my case it was showing 1, meaning the population was in progress. After about a couple of hours it was still showing 1 and just stayed there. When I checked the ItemCount property returned by the same function, it was showing 0, meaning no items had been indexed so far.These were clear signs that the data population process was stuck.
 
I looked at the scripts and the tables and the catalogs and indexes, but didnt find anything amiss. I then checked the logs in the SQL Install folder and noticed the following error related to Full-Text Search:
 
"No Mapping between account names and security id's were done"
 
I had no idea where this error was coming from and it took me some time before I hit upon the idea of checking the Full-Text Search Windows Service. It turned out that the Service was running under a user account Admin123 that no longer existed on the machine. I changed the Service to run under the Local System Account and everything started working!!!

10/31/10

System.Threading.Timer

I have a data population task inside a windows service that needs to start on a certain date and repeat periodically at a specified interval. The start date and the repeat interval can be specified through a xml config file.

I decided to use the Timer class in the System.Threading namespace. It has a number of  constructor overloads and the following is the one I used :

public Timer(TimerCallback callback, Object state, TimeSpan dueTime, TimeSpan period);

where:

callback -> The method that performs the task.

It must match the signature of the System.Threading.TimerCallback delegate type that has the following signature:

delegate void TimerCallback(Object state)

state -> data that you can pass to the callback method each time it is invoked.

dueTime - > the amount of time the CLR needs to wait before calling the callback method the first time.

period -> the repeat interval

The advantage of using this Timer class is that the callback method is called by a CLR thread pool thread. The Thread Pool assigns one thread from the pool for all Timer instances. This thread keeps track of all the timers and calls them at their due time.



(reference : CLR via C# - Jeffrey Richter)

10/24/10

Full-Text Search in SQL Server 2005

Full-Text search is a SQL Server feature that provides powerful options for querying text information in the database.Without this feature the querying options are pretty much limited to using the LIKE clause or using functions such as PATINDEX and CHARINDEX.

The Full-Text Search is implemented via a Full-Text Search Windows Service. This Service is NOT a part of  the SQL Server. The SQL Server interacts with this external service in order to facilitate Full-Text Search.

Following are the steps to enable Full-Text Search in a database:

  • Make a list of tables that need to be Full-Text search enabled.
  • In each of the tables, make a list of all the columns that need to be a part of the Full-Text Search index.
  • Create a Catalog, specifying a location for its creation. A Catalog is a container that holds Indexes. You can have as many Catalogs as you like and each Catalog can hold zero or more indexes. Though external to the SQL Server, the Catalogs need to be on same machine as the SQL Server. For performance reasons, Microsoft recommends creating the Catalogs in a drive separate from that of  the SQL Server installation. Microsoft also recommends creating separate Catalogs for tables that have more than one million rows of data.
  • Create one Index per table. You can have only one index per table. Also you need to specify the Catalog the index belongs to.An Index can belong to only one Catalog.
  • At this point, we only have the structure(catalogs and indexes) but no data. We need to populate(crawl) the indexes. Population is the process of SQL Server passing data from the indexed columns to the Full-Text Service, which maintains a word list letting us know what words can be found in what rows. It is a resource and memory intensive action that must be performed during off-peak hours so as to not slow down the SQL Server.Once the population is complete, the tables are Full-Text Search enabled.
  • Next, all the database objects like Stored Procedures, Functions and Views need to be modified to use the Full-Text syntax. The Full-Text syntax contains commands like CONTAINS,CONTAINSTABLE, FREETEXT, FREETEXTTABLE etc that enable us to query for information in different ways.
  • Full-Text indexes are not kept up to date like SQL Server indexes.So, if new data is added to the tables, the data will not be searchable until the indexes on those tables are re-populated.