<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>.NET Gotchas</title>
        <link>http://geekswithblogs.net/chrisfalter/category/4241.aspx</link>
        <description>If you're like me, you regularly encounter those "gotchas" with the .NET Framework.  They might happen because the documentation is poor, or you assumed something you shouldn't have, or even, on the rare occasion, because Microsoft's implementation is kludgey.  When I encounter a gotcha, I'll post a word to the wise here so you can avoid it.</description>
        <language>en-US</language>
        <copyright>Chris Falter</copyright>
        <managingEditor>chrisfalter@yahoo.com</managingEditor>
        <generator>Subtext Version 0.0.0.0</generator>
        <item>
            <title>Of Sobriety Tests and Loop Iteration</title>
            <link>http://geekswithblogs.net/chrisfalter/archive/2007/11/08/116713.aspx</link>
            <description>&lt;p&gt;A few years ago I listened in fascination to a radio interview with a highway patrol officer who was describing how she conducted field sobriety tests.  In addition to the typical tests of walking in a straight line and of standing on one foot, she would ask the erratic driver to recite the alphabet.  One driver slurred, "A.  Is that good enough?"  "That's all the alphabet you can recite?" she responded.  "Yep," he answered.  She booked him.  She would also ask drivers to count backwards from 100.  If a driver skipped around or had to think hard, his mental facilities were not sharp enough to permit him to drive safely.&lt;/p&gt;
&lt;p&gt;Counting backwards can also come in handy when you're performing a loop iteration.  For years we had some data access code that looped through a DataRowCollection in order to commit changes to a DB2 database:&lt;/p&gt;
&lt;div style="FONT-SIZE: 9pt; FONT-FAMILY: monospace; BACKGROUND-COLOR: white"&gt;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt;&lt;span style="COLOR: black"&gt; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;void&lt;/span&gt;&lt;span style="COLOR: black"&gt; SaveRows(DataTable tbl)&lt;br /&gt;
{&lt;br /&gt;
    &lt;/span&gt;&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;&lt;span style="COLOR: black"&gt; spName = &lt;/span&gt;&lt;span style="COLOR: blue"&gt;null&lt;/span&gt;&lt;span style="COLOR: black"&gt;;&lt;br /&gt;
    &lt;/span&gt;&lt;span style="COLOR: blue"&gt;for&lt;/span&gt;&lt;span style="COLOR: black"&gt; (&lt;/span&gt;&lt;span style="COLOR: blue"&gt;int&lt;/span&gt;&lt;span style="COLOR: black"&gt; i = 0; i &amp;lt; tbl.Rows.Count; i++)&lt;br /&gt;
    {&lt;br /&gt;
        DataRow row = tbl.Rows[i];&lt;br /&gt;
        DataRowState rowState = row.RowState;&lt;br /&gt;
        &lt;/span&gt;&lt;span style="COLOR: blue"&gt;if&lt;/span&gt;&lt;span style="COLOR: black"&gt; ((rowState &amp;amp; DataRowState.Unchanged) &amp;gt; 0)&lt;br /&gt;
            &lt;/span&gt;&lt;span style="COLOR: blue"&gt;continue&lt;/span&gt;&lt;span style="COLOR: black"&gt;;&lt;br /&gt;
        &lt;/span&gt;&lt;span style="COLOR: blue"&gt;switch&lt;/span&gt;&lt;span style="COLOR: black"&gt; (row.RowState)&lt;br /&gt;
        {&lt;br /&gt;
            &lt;/span&gt;&lt;span style="COLOR: blue"&gt;case&lt;/span&gt;&lt;span style="COLOR: black"&gt; DataRowState.Added:&lt;br /&gt;
                spName = &lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;"SPI"&lt;/span&gt;&lt;span style="COLOR: black"&gt; + tbl.TableName;&lt;br /&gt;
                &lt;/span&gt;&lt;span style="COLOR: blue"&gt;break&lt;/span&gt;&lt;span style="COLOR: black"&gt;;&lt;br /&gt;
            &lt;/span&gt;&lt;span style="COLOR: blue"&gt;case&lt;/span&gt;&lt;span style="COLOR: black"&gt; DataRowState.Modified:&lt;br /&gt;
                spName = &lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;"SPU"&lt;/span&gt;&lt;span style="COLOR: black"&gt; + tbl.TableName;&lt;br /&gt;
                &lt;/span&gt;&lt;span style="COLOR: blue"&gt;break&lt;/span&gt;&lt;span style="COLOR: black"&gt;;&lt;br /&gt;
            &lt;/span&gt;&lt;span style="COLOR: blue"&gt;case&lt;/span&gt;&lt;span style="COLOR: black"&gt; DataRowState.Deleted:&lt;br /&gt;
                spName = &lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;"SPD"&lt;/span&gt;&lt;span style="COLOR: black"&gt; + tbl.TableName;&lt;br /&gt;
                &lt;/span&gt;&lt;span style="COLOR: blue"&gt;break&lt;/span&gt;&lt;span style="COLOR: black"&gt;;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;/span&gt;&lt;span style="COLOR: blue"&gt;try&lt;br /&gt;
&lt;/span&gt;&lt;span style="COLOR: black"&gt;        {&lt;br /&gt;
            IDbDataParameter[] parms = DataHelperParameterCache.GetSpParameterSet(DataHelper.ConnectionString, spName);&lt;br /&gt;
            CallStoredProc(spName, parms, row);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;/span&gt;&lt;span style="COLOR: blue"&gt;catch&lt;/span&gt;&lt;span style="COLOR: black"&gt; (&lt;/span&gt;&lt;span style="COLOR: #2b91af"&gt;Exception&lt;/span&gt;&lt;span style="COLOR: black"&gt; ex)&lt;br /&gt;
        {&lt;br /&gt;
            &lt;/span&gt;&lt;span style="COLOR: blue"&gt;if&lt;/span&gt;&lt;span style="COLOR: black"&gt; (tx != &lt;/span&gt;&lt;span style="COLOR: blue"&gt;null&lt;/span&gt;&lt;span style="COLOR: black"&gt;)&lt;br /&gt;
            {&lt;br /&gt;
                tx.Rollback();&lt;br /&gt;
                rolledBack = &lt;/span&gt;&lt;span style="COLOR: blue"&gt;true&lt;/span&gt;&lt;span style="COLOR: black"&gt;;&lt;br /&gt;
            }&lt;br /&gt;
            &lt;/span&gt;&lt;span style="COLOR: blue"&gt;throw&lt;/span&gt;&lt;span style="COLOR: black"&gt; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;new&lt;/span&gt;&lt;span style="COLOR: black"&gt; BaseApplicationException(&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;"Fatal Exception while running stored proc "&lt;/span&gt;&lt;span style="COLOR: black"&gt; + spName, ex);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;Then after we had called this function on all the DataTables in the DataSet, we called DataSet.AcceptChanges().  This code generally worked well.&lt;/p&gt;
&lt;p&gt;Then one day we realized that by not using a IDbTransaction (we left it null) and calling DataSet.AcceptChanges() at the end, we would leave our DataSet in a state inconsistent with the data store if a failure occurred part way through the process of saving tables and rows.  For example, if a row had been inserted to the data store, but AcceptChanges() had not been called, then its RowState was still DataRowState.Added.  And the next time a user tried to save his work, our system would try to insert an additional row, rather than updating the row that was already in the data store.  So we decided to call DataRow.AcceptChanges() after each row operation (after the call to CallStoredProc in the above code).&lt;/p&gt;
&lt;p&gt;A few days later, our testers reported that the last of 2 delete operations would no longer commit to the data store.  What?  How could adopting a new strategy for accepting changes cause that kind of bug?&lt;/p&gt;
&lt;p&gt;Well, what happens when you call DataRow.AcceptChanges() when the RowState is DataRowState.Deleted?  Poof!  It vanishes into thin air.  As a result, the next row would get skipped over in the loop iteration, since its ordinal had shifted back by one.  &lt;/p&gt;
&lt;p&gt;Allow me to illustrate: you've got 2 rows, and you're going through the loop.  The first time you enter the loop body, &lt;em&gt;i&lt;/em&gt; is 0 and you're working with Rows[0], the first row.  Before you finish the loop, you call DataRow.AcceptChanges(), and the row disappears in a cloud of smoke, &lt;em&gt;alakazam!&lt;/em&gt;  Now the row that used to be at Rows[1] shifts back to Rows[0], and Rows.Count == 1.  And we're at the end the loop, so we increment &lt;em&gt;i&lt;/em&gt; to 1 and do the test:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;i &amp;lt; tbl.Rows.Count&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This statement is false, so we exit the &lt;em&gt;for&lt;/em&gt; loop.  Thus the row that shifted from index 1 to index 0 (when its sibling vanished) never got processed.&lt;/p&gt;
&lt;p&gt;My first thought on fixing the problem was to use a &lt;em&gt;foreach&lt;/em&gt; loop and let it figure out how to deal with the deletion for me.  However, the DataRowCollection quite correctly threw an &lt;em&gt;InvalidOperationException&lt;/em&gt; when we tried it, and I can't blame the class designers for the behavior.  Remember, the iterator is supposed to keep track of the Current and the Next member of the collection as you traverse it.  But if you delete the Current member, where should Current point to?  Can it point to the member of the collection immediately following the deleted member?  Not really; Current and Next would then be referring to the same member.  And if the iterator shifted the Next by one to avoid the clash, the same way it shifted Current by one, we might skip over the collection member that immediately follows the deleted member when the iterator's MoveNext method is called.  As the .NET Framework documentation states:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;The &lt;strong&gt;foreach&lt;/strong&gt; statement is used to iterate through the collection to get the desired information, but should &lt;strong&gt;not&lt;/strong&gt; be used to change the contents of the collection to avoid unpredictable side effects.&lt;/em&gt; [emphasis mine]&lt;/p&gt;
&lt;p&gt;My colleague Kyle then came up with a terrific idea: just count backwards!  Start at the last member and iterate back to the first; and if a member is deleted, the loop still operates correctly.   So now our code looks like this:&lt;/p&gt;
&lt;div style="FONT-SIZE: 9pt; FONT-FAMILY: monospace; BACKGROUND-COLOR: white"&gt;&lt;span style="COLOR: blue"&gt;for&lt;/span&gt;&lt;span style="COLOR: black"&gt; (&lt;/span&gt;&lt;span style="COLOR: blue"&gt;int&lt;/span&gt;&lt;span style="COLOR: black"&gt; i = tbl.Rows.Count - 1; i &amp;gt;= 0; i--)&lt;br /&gt;
{&lt;br /&gt;
    &lt;/span&gt;&lt;span style="COLOR: green"&gt;// everything else is the same as before&lt;br /&gt;
&lt;/span&gt;&lt;span style="COLOR: black"&gt;}&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;You might not think the great programmers grow up in Appalachian hill country, but Kentucky Kyle has been full of pleasant surprises for us ever since we were astute enough to hire him.  Or maybe they just have to deal with field sobriety tests a lot more in the Kentucky hills.  Whatever the background, my hat is off to Kyle for his excellent idea.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=116713"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=116713" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/chrisfalter/aggbug/116713.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Chris Falter</dc:creator>
            <guid>http://geekswithblogs.net/chrisfalter/archive/2007/11/08/116713.aspx</guid>
            <pubDate>Thu, 08 Nov 2007 11:44:40 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/chrisfalter/comments/116713.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/chrisfalter/archive/2007/11/08/116713.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/chrisfalter/comments/commentRss/116713.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/chrisfalter/services/trackbacks/116713.aspx</trackback:ping>
        </item>
        <item>
            <title>Website Projects and Windows Authentication: a Volatile Mixture</title>
            <link>http://geekswithblogs.net/chrisfalter/archive/2007/11/02/116560.aspx</link>
            <description>&lt;p&gt;Vinegar is an important ingredient in the kitchen; with it you can make &lt;a href="http://homecooking.about.com/od/porkrecipes/r/blpork77.htm"&gt;baked tropical spareribs&lt;/a&gt;, &lt;a href="http://homecooking.about.com/library/archive/bllamb25.htm"&gt;Indian mutton curry&lt;/a&gt;, &lt;a href="http://homecooking.about.com/od/saladrecipes/r/blsalad50.htm"&gt;orange almond greens&lt;/a&gt; and a &lt;a href="http://homecooking.about.com/library/archive/blvinegar.htm"&gt;host of other delightful dishes&lt;/a&gt;.  Baking soda, too, is an essential ingredient in &lt;a href="http://homecooking.about.com/od/cakerecipes/r/blc85.htm"&gt;nutmeg raisin coffee cake&lt;/a&gt;, &lt;a href="http://baking.about.com/od/sweetrolls/r/buckwheat.htm"&gt;buckwheat pancakes&lt;/a&gt;, and many other delectable baked goods.  Both are useful, reliable, and safe in storage.  However, as any fourth-grader who has ever attended a science fair can tell you, all you have to do is mix the two to create a volcano that will spill lots of red, flowing "lava" all over your kitchen tile.&lt;/p&gt;
&lt;p&gt;Today one of my colleagues inadvertantly created a code volcano when he incorrectly mixed Windows authentication with an ASP.NET 2.0 website project.  (Of course, I was responsible for reviewing the code &lt;em&gt;[Ahem!]&lt;/em&gt; so I'm in no position to point fingers.)&lt;/p&gt;
&lt;p&gt;The site has the responsibility of displaying GIS data to internal users.  Certain of the data are restricted to users who belong to certain Windows groups; the restriction is managed through database views.  My initial thought was to create a separate directory for each group, and to let each page in a directory derive from a custom page class which would define the database view to use.  Then we could write a location element in web.config with a directory-specific &lt;em&gt;authentication&lt;/em&gt; element (under &lt;em&gt;system.web&lt;/em&gt;) to ensure that only the members of the appropriate group could view the directory's pages.  &lt;/p&gt;
&lt;p&gt;But my colleague had a much better idea; the main site could select the appropriate view based on the group membership(s) of the logged-in user.  The code he checked in this morning for the site's base page class contained the following:&lt;/p&gt;
&lt;div style="FONT-SIZE: 9pt; FONT-FAMILY: monospace; BACKGROUND-COLOR: white"&gt;    &lt;span style="COLOR: blue"&gt;Public&lt;/span&gt;&lt;span style="COLOR: black"&gt; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;ReadOnly&lt;/span&gt;&lt;span style="COLOR: black"&gt; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;Property&lt;/span&gt;&lt;span style="COLOR: black"&gt; UserGroups() &lt;/span&gt;&lt;span style="COLOR: blue"&gt;As&lt;/span&gt;&lt;span style="COLOR: black"&gt; List(&lt;/span&gt;&lt;span style="COLOR: blue"&gt;Of&lt;/span&gt;&lt;span style="COLOR: black"&gt; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;String&lt;/span&gt;&lt;span style="COLOR: black"&gt;)&lt;br /&gt;
        &lt;/span&gt;&lt;span style="COLOR: blue"&gt;Get&lt;br /&gt;
&lt;/span&gt;&lt;span style="COLOR: black"&gt;            &lt;/span&gt;&lt;span style="COLOR: blue"&gt;Dim&lt;/span&gt;&lt;span style="COLOR: black"&gt; groups &lt;/span&gt;&lt;span style="COLOR: blue"&gt;As&lt;/span&gt;&lt;span style="COLOR: black"&gt; List(&lt;/span&gt;&lt;span style="COLOR: blue"&gt;Of&lt;/span&gt;&lt;span style="COLOR: black"&gt; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;String&lt;/span&gt;&lt;span style="COLOR: black"&gt;) = &lt;/span&gt;&lt;span style="COLOR: blue"&gt;New&lt;/span&gt;&lt;span style="COLOR: black"&gt; List(&lt;/span&gt;&lt;span style="COLOR: blue"&gt;Of&lt;/span&gt;&lt;span style="COLOR: black"&gt; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;String&lt;/span&gt;&lt;span style="COLOR: black"&gt;)()&lt;br /&gt;
&lt;br /&gt;
            &lt;/span&gt;&lt;span style="COLOR: blue"&gt;For&lt;/span&gt;&lt;span style="COLOR: black"&gt; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;Each&lt;/span&gt;&lt;span style="COLOR: black"&gt; idref &lt;/span&gt;&lt;span style="COLOR: blue"&gt;As&lt;/span&gt;&lt;span style="COLOR: black"&gt; IdentityReference &lt;/span&gt;&lt;span style="COLOR: blue"&gt;In&lt;/span&gt;&lt;span style="COLOR: black"&gt; WindowsIdentity.GetCurrent().Groups&lt;br /&gt;
                groups.Add(idref.Translate(&lt;/span&gt;&lt;span style="COLOR: blue"&gt;GetType&lt;/span&gt;&lt;span style="COLOR: black"&gt;(NTAccount)).Value)&lt;br /&gt;
            &lt;/span&gt;&lt;span style="COLOR: blue"&gt;Next&lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt;&lt;span style="COLOR: black"&gt;            &lt;/span&gt;&lt;span style="COLOR: blue"&gt;Return&lt;/span&gt;&lt;span style="COLOR: black"&gt; groups&lt;br /&gt;
        &lt;/span&gt;&lt;span style="COLOR: blue"&gt;End&lt;/span&gt;&lt;span style="COLOR: black"&gt; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;Get&lt;br /&gt;
&lt;/span&gt;&lt;span style="COLOR: black"&gt;    &lt;/span&gt;&lt;span style="COLOR: blue"&gt;End&lt;/span&gt;&lt;span style="COLOR: black"&gt; &lt;/span&gt;&lt;span style="COLOR: blue"&gt;Property&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;p&gt;The page class would then check for group memberships (in order from least restrictive to most restrictive) in the List&amp;lt;string&amp;gt;.  It would select the database view that corresponded to the first match.  If it did not find a match, it would transfer the user to an error page ("Unauthorized.aspx").&lt;/p&gt;
&lt;p&gt;To test this design my colleague ran the site in debug mode on his machine, and saw that he was able to use the view corresponding to his group membership.  To test users with other group memberships, he turned on Windows impersonation in web.config...&lt;/p&gt;
&lt;div style="FONT-SIZE: 9pt; FONT-FAMILY: monospace; BACKGROUND-COLOR: white"&gt;&lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;identity&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;impersonate&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;&lt;span style="COLOR: black"&gt;"&lt;/span&gt;&lt;span style="COLOR: blue"&gt;true&lt;/span&gt;&lt;span style="COLOR: black"&gt;"&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;userName&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;&lt;span style="COLOR: black"&gt;"&lt;/span&gt;&lt;span style="COLOR: blue"&gt;MyDomain\TestGroupMember&lt;/span&gt;&lt;span style="COLOR: black"&gt;"&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;password&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;&lt;span style="COLOR: black"&gt;"&lt;/span&gt;&lt;span style="COLOR: blue"&gt;TestGroupMember&lt;/span&gt;&lt;span style="COLOR: black"&gt;"&lt;/span&gt;&lt;span style="COLOR: blue"&gt;/&amp;gt;&lt;/span&gt; &lt;/div&gt;
&lt;p&gt;&lt;font face="Arial"&gt;...and everything worked as expected.  He commented out the identity node in web.config, checked in his code, and we promoted it to a test environment.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;Knowledgeable readers can anticipate what happened next: when I accessed the site's index.aspx on the host server, I got a chance to review the look-and-feel of Unauthorized.aspx, even though I was a member of the least restricted group.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;So why was the behavior different running on IIS than on the developer machine?  On a developer machine, the website is hosted in a process called &lt;em&gt;WebDev.WebServer.EXE&lt;/em&gt; running under the identity of the Visual Studio 2005 user.  On Windows 2003, though, the website is hosted by an app pool running under the identity of whatever's configured in IIS (by default, the server's "Network Service" user).  The &lt;em&gt;UserGroup&lt;/em&gt; property's call to &lt;strong&gt;WindowsIdentity.GetCurrent()&lt;/strong&gt; returns the Windows identity of the host process, &lt;strong&gt;*not*&lt;/strong&gt; the WindowsIdentity of the authenticated user.  When the code ran on a developer machine, this was not a problem; the identity of the site's user and the host process were identical.  But when the code ran on a server, it would try to find a database view associated with the "Network Service" user.  And since none existed, it would refer the user to Unauthorized.aspx.  &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;(Note to self: never repeat the mistake of testing user logins via identity impersonation.)&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Once we understood the error, correcting it was not too difficult.  My colleague simply called the (System.Web.Security) &lt;strong&gt;Roles.IsUserInRole()&lt;/strong&gt; method, passing in the role names from least restrictive to most restrictive.  Behind the scenes, ASP.NET is basing its role management on the logged-in user's roles.  When a site is configured to use Windows authentication, the user's roles are the same as the user's Windows group memberships.  Now everything works the way it's supposed to, and Daddy can go home and have dinner with his family.&lt;/p&gt;
&lt;p&gt;&lt;font face="Arial"&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=116560"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=116560" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/chrisfalter/aggbug/116560.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Chris Falter</dc:creator>
            <guid>http://geekswithblogs.net/chrisfalter/archive/2007/11/02/116560.aspx</guid>
            <pubDate>Fri, 02 Nov 2007 15:01:43 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/chrisfalter/comments/116560.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/chrisfalter/archive/2007/11/02/116560.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/chrisfalter/comments/commentRss/116560.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/chrisfalter/services/trackbacks/116560.aspx</trackback:ping>
        </item>
        <item>
            <title>Do *NOT* Set up a Reparse Point for the Windows\Assembly Folder!</title>
            <link>http://geekswithblogs.net/chrisfalter/archive/2007/07/16/113979.aspx</link>
            <description>&lt;p&gt;Our build server (running Windows 2003 Server) was set up with 2 partitions: a small system partition (C:) and a large data partition (D:).  As we installed more and more  software packages on it, the system drive filled to capacity.  In order to free space on the system partition, we moved a variety of directories from drive C to drive D, and then used the &lt;a target="_blank" href="http://www.microsoft.com/technet/sysinternals/FileAndDisk/Junction.mspx"&gt;Junction utility&lt;/a&gt; from &lt;a target="_blank" href="http://www.microsoft.com/technet/sysinternals/default.mspx"&gt;SysInternals&lt;/a&gt; (now owned by Microsoft) to create reparse points on drive C that pointed to the new file locations on drive D.  A reparse point is a symbolic link that redirects a file request from one point to another on the same computer.  In this case, the reparse points allowed applications to access files supposedly on drive C, while in fact they were on drive D.  Storage problem solved, all was well...or so we thought.&lt;/p&gt;
&lt;p&gt;This storage reconfiguration strategy can be successfully applied for user profiles (via C:\Documents and Settings\) and a variety of applications that install to C:\Program Files by default.  However, our decision to redirect file requests for the Global Assembly Cache (located at C:\Windows\Assembly) blew up in our faces when the most recent Windows security update (&lt;a target="_blank" href="http://support.microsoft.com/kb/928365"&gt;KB 928365&lt;/a&gt;, which corresponds to security bulletin &lt;a target="_blank" href="http://www.microsoft.com/technet/security/bulletin/ms07-040.mspx"&gt;MS07-040&lt;/a&gt;) was installed.  After the build server was rebooted, we suddenly started seeing the following error show up in a variety of contexts:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;Could not load file or assembly 'System.EnterpriseServices, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'&lt;/strong&gt;&lt;/font&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Web services and web applications running in ASP.NET 2.0 threw this error on first request, and Visual Studio 2005 builds/compiles would report this error as well.  We tried a variety of troubleshooting steps, such as rolling back the security update, and reinstalling .NET Framework 2.0, but nothing worked...that is, nothing worked until we removed the reparse point for the GAC.  Once we moved the GAC's physical file location back to C:\Windows\Assembly, everything suddenly began to function correctly.&lt;/p&gt;
&lt;p&gt;Evidently there is some kind of security setting in the .NET Framework which does not allow updates to some (or all) of its assemblies anywhere outside of the original GAC location.  For the time being, I do not have the time to satisfy my curiosity by researching why this is so.  However, I do have a few minutes to warn my readers not to fall into the same trap: do not create a reparse point for the GAC folder!&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=113979"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=113979" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/chrisfalter/aggbug/113979.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Chris Falter</dc:creator>
            <guid>http://geekswithblogs.net/chrisfalter/archive/2007/07/16/113979.aspx</guid>
            <pubDate>Mon, 16 Jul 2007 13:31:27 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/chrisfalter/comments/113979.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/chrisfalter/archive/2007/07/16/113979.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/chrisfalter/comments/commentRss/113979.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/chrisfalter/services/trackbacks/113979.aspx</trackback:ping>
        </item>
        <item>
            <title>How To: Write a Unit Test for Multi-Dimensioned Output</title>
            <link>http://geekswithblogs.net/chrisfalter/archive/2007/05/04/112254.aspx</link>
            <description>&lt;p&gt;One of the cool features of Visual Studio 2005 is that it can generate a unit test stub for a class or method.  However, I recently discovered that the Unit Test plug-in does not know how to auto-generate an assertion for a method whose output includes a multi-dimensioned out parameter or return value.  Here's the relevant stub code that VS 2005 generated for one of my methods whose output includes a multi-dimensioned array:&lt;/p&gt;
&lt;div class="code"&gt;
&lt;p&gt;&lt;font color="#008000" size="2"&gt;// generated code that creates a class instance called "target", plus other input + expected output parameters&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;font size="2"&gt;[][]&lt;/font&gt; homeAttributes;&lt;br /&gt;
&lt;font color="#0000ff"&gt;string&lt;/font&gt;&lt;font size="2"&gt;[][]&lt;/font&gt; homeAttributes_expected = null; &lt;font color="#008000" size="2"&gt;// TODO: Initialize to an appropriate value&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;target.MethodBeingTested(in1, in2, &lt;font color="#0000ff"&gt;out&lt;/font&gt; homeAttributes)&lt;/font&gt;&lt;/p&gt;
&lt;font size="2"&gt;
&lt;p&gt;&lt;font color="#2b91af" size="2"&gt;CollectionAssert&lt;/font&gt;.AreEqual(homeAttributes_expected[i], homeAttributes[i], &lt;font color="#a31515" size="2"&gt;"homeAttributes was not set correctly."&lt;/font&gt;);&lt;/p&gt;
&lt;/font&gt;&lt;/div&gt;
&lt;p&gt;&lt;font size="2"&gt;So I edited the code to initialize homeAttributes_expected, then ran the unit test, and it failed.  Okay, my code must have a bug...but when I reviewed the code for MethodBeingTested(), it sure looked right.  Then I stepped through the unit test in debug mode.  However, when I hit the breakpoint on &lt;font color="#2b91af" size="2"&gt;CollectionAssert&lt;/font&gt;.AreEqual() and expanded the arrays, the data was exactly what I expected it to be.  So maybe my initialization code for homeAttributes_expected was wrong...but no, it looked right.  What was wrong with this picture?&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;(These are the kind of challenges that either bring out the best or the worst in a software developer.  You either rise to the occasion, or become a broken, miserable, and somewhat sneaky creature that silently excises the &lt;font color="#2b91af" size="2"&gt;CollectionAssert&lt;/font&gt;.AreEqual() statement so the unit test will pass.  And I was not about to steal away quietly!)&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;I realized what must be happening: &lt;font color="#2b91af" size="2"&gt;CollectionAssert&lt;/font&gt;.AreEqual() must be calling the object.Equals() method to compare each member of the collections.  And in a multi-dimensioned array, the collection object being tested (the array of arrays) consists of members that are themselves collections (i.e., arrays).  Since the built-in Array class in the .NET Framework does not override the object.Equals() method, &lt;font color="#2b91af" size="2"&gt;CollectionAssert&lt;/font&gt;.AreEqual() will use the default object.Equals() method to compare the &lt;em&gt;identity &lt;/em&gt;of the array members; in other words, it compares the address of the 2 arrays in memory.  These will of course be different, so the assertion fails, and the unit test fails.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;You have probably noticed that this post claims to apply to all multi-dimensioned output.  That's because you will encounter the same problem if your output is a &lt;font color="#2b91af" size="2"&gt;List&lt;/font&gt;&amp;lt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&amp;gt;[], or a &lt;font color="#2b91af" size="2"&gt;List&lt;/font&gt;&amp;lt;&lt;font color="#2b91af" size="2"&gt;List&lt;/font&gt;&amp;lt;&lt;font color="#0000ff"&gt;string&lt;/font&gt;&amp;gt;&amp;gt;, or any other multi-dimensioned object.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;Fortunately, you can conquer this problem with some clever refactoring.  Just iterate through the outer dimension, and call &lt;font color="#2b91af" size="2"&gt;CollectionAssert&lt;/font&gt;.AreEqual on the inner collections.  Write your code like this, and everything will work just the way you want it to:&lt;/font&gt;&lt;/p&gt;
&lt;div class="code"&gt;
&lt;p&gt;&lt;font size="2"&gt;&lt;font color="#0000ff" size="2"&gt;for&lt;/font&gt;&lt;font size="2"&gt; (&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;int&lt;/font&gt; i = 0; i &amp;lt; homeAttributes_expected.GetLength(0); i++)&lt;br /&gt;
{&lt;br /&gt;
  &lt;font color="#2b91af" size="2"&gt;CollectionAssert&lt;/font&gt;.AreEqual(homeAttributes_expected[i], homeAttributes[i], &lt;font color="#a31515" size="2"&gt;"MethodBeingTested_homeAttributes_expected was not set correctly at index "&lt;/font&gt; + i.ToString());&lt;br /&gt;
}&lt;/font&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Now &lt;font color="#2b91af" size="2"&gt;CollectionAssert&lt;/font&gt;.AreEqual() compares two single-dimensioned collections each time it is called.  As a result, when it calls object.Equals() on the members of the collections, it will use the member type's override of object.Equals()--in this case, String.Equals()--and the assertion works correctly.&lt;/p&gt;
&lt;p&gt;Happy unit testing!&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=112254"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=112254" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/chrisfalter/aggbug/112254.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Chris Falter</dc:creator>
            <guid>http://geekswithblogs.net/chrisfalter/archive/2007/05/04/112254.aspx</guid>
            <pubDate>Fri, 04 May 2007 13:42:42 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/chrisfalter/comments/112254.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/chrisfalter/archive/2007/05/04/112254.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/chrisfalter/comments/commentRss/112254.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/chrisfalter/services/trackbacks/112254.aspx</trackback:ping>
        </item>
        <item>
            <title>More on How To Re-throw an Exception</title>
            <link>http://geekswithblogs.net/chrisfalter/archive/2007/03/28/110136.aspx</link>
            <description>&lt;P&gt;Re-throwing an exception is a little more complex that I had realized.&amp;nbsp; The gotcha, pointed out by helpful reader "Sander", is that when the initial exception is thrown from directly inside the try block, rather than from within a method call inside the try block, you will lose the line number of the faulty line of code, regardless of how you re-throw the exception.&amp;nbsp; Here's some sample code that demonstrates what I mean:&lt;/P&gt;
&lt;DIV style="FONT-SIZE: 8pt; FONT-FAMILY: monospace; BACKGROUND-COLOR: white"&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;FONT size=1&gt;using&lt;/FONT&gt;&lt;/SPAN&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt; System;&lt;BR&gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;namespace&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt; RethrowExTest&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt; &lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN style="COLOR: #2b91af"&gt;&lt;FONT size=1&gt;Program&lt;BR&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt; Main(&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;[] args)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt;.WriteLine(&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;"Whoops! Re-throw from procedural code loses the line number of the exception"&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN style="COLOR: black"&gt;&lt;FONT size=1&gt;);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;FONT size=1&gt;try&lt;BR&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt;&lt;FONT size=1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;FONT size=1&gt;try&lt;BR&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt; zero = 0;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt; i = 1 / zero;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;catch&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt; (&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Exception&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt; ex)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt;.WriteLine(&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;"Inner catch:"&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;.WriteLine(ex.Message);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;.WriteLine(ex.StackTrace);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;throw&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;catch&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt; (&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Exception&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt; ex)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt;.WriteLine(&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;"Outer catch:"&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;.WriteLine(ex.Message);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;.WriteLine(ex.StackTrace);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;.WriteLine();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt;.WriteLine(&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;"However, re-throw from exception-throwing method retains the line number, as expected"&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN style="COLOR: black"&gt;&lt;FONT size=1&gt;);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;FONT size=1&gt;try&lt;BR&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt;&lt;FONT size=1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;FONT size=1&gt;try&lt;BR&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MethodThatThrowsException();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;catch&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt; (&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Exception&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt; ex)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt;.WriteLine(&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;"Inner catch:"&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;.WriteLine(ex.Message);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;.WriteLine(ex.StackTrace);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;throw&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;catch&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt; (&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Exception&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt; ex)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt;.WriteLine(&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;"Outer catch:"&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;.WriteLine(ex.Message);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;.WriteLine(ex.StackTrace);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;.WriteLine();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt;.WriteLine(&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;"New throw from procedural code loses the line number, as expected"&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN style="COLOR: black"&gt;&lt;FONT size=1&gt;);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;FONT size=1&gt;try&lt;BR&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt;&lt;FONT size=1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;FONT size=1&gt;try&lt;BR&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt; zero = 0;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt; i = 1 / zero;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;catch&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt; (&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Exception&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt; ex)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt;.WriteLine(&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;"Inner catch:"&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;.WriteLine(ex.Message);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;.WriteLine(ex.StackTrace);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;throw&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt; ex;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;catch&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt; (&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Exception&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt; ex)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt;.WriteLine(&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;"Outer catch:"&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;.WriteLine(ex.Message);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;.WriteLine(ex.StackTrace);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;.WriteLine();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt;.WriteLine(&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;"New throw from method loses the line number, as expected"&lt;/SPAN&gt;&lt;/FONT&gt;&lt;SPAN style="COLOR: black"&gt;&lt;FONT size=1&gt;);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;FONT size=1&gt;try&lt;BR&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt;&lt;FONT size=1&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;FONT size=1&gt;try&lt;BR&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MethodThatThrowsException();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;catch&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt; (&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Exception&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt; ex)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt;.WriteLine(&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;"Inner catch:"&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;.WriteLine(ex.Message);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;.WriteLine(ex.StackTrace);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;throw&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt; ex;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;catch&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt; (&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Exception&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt; ex)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt;.WriteLine(&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;"Outer catch:"&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;.WriteLine(ex.Message);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #2b91af"&gt;Console&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt;.WriteLine(ex.StackTrace);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;private&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt; MethodThatThrowsException()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt; zero = 0;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;int&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;SPAN style="COLOR: black"&gt; i = 1 / zero;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;}&lt;/SPAN&gt; &lt;/FONT&gt;&lt;/DIV&gt;
&lt;P&gt;The output looks just like what we expected:&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Tahoma size=1&gt;&lt;STRONG&gt;Whoops! Re-throw from procedural code loses the line number of the exception&lt;BR&gt;&lt;/STRONG&gt;Inner catch:&lt;BR&gt;Attempted to divide by zero.&lt;BR&gt;&amp;nbsp;&amp;nbsp; at RethrowExTest.Program.Main(String[] args) in C:\Projects\Tests\RethrowExceptions\RethrowExTest\Program.cs:&lt;STRONG&gt;line 15&lt;BR&gt;&lt;/STRONG&gt;Outer catch:&lt;BR&gt;Attempted to divide by zero.&lt;BR&gt;&amp;nbsp;&amp;nbsp; at RethrowExTest.Program.Main(String[] args) in C:\Projects\Tests\RethrowExceptions\RethrowExTest\Program.cs:&lt;STRONG&gt;line 22&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;However, re-throw from exception-throwing method retains the line number, as expected&lt;BR&gt;&lt;/STRONG&gt;Inner catch:&lt;BR&gt;Attempted to divide by zero.&lt;BR&gt;&amp;nbsp;&amp;nbsp; at RethrowExTest.Program.MethodThatThrowsException() in C:\Projects\Tests\RethrowExceptions\RethrowExTest\Program.cs:&lt;STRONG&gt;line 103&lt;/STRONG&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; at RethrowExTest.Program.Main(String[] args) in C:\Projects\Tests\RethrowExceptions\RethrowExTest\Program.cs:line 37&lt;BR&gt;Outer catch:&lt;BR&gt;Attempted to divide by zero.&lt;BR&gt;&amp;nbsp;&amp;nbsp; at RethrowExTest.Program.MethodThatThrowsException() in C:\Projects\Tests\RethrowExceptions\RethrowExTest\Program.cs:&lt;STRONG&gt;line 103&lt;/STRONG&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; at RethrowExTest.Program.Main(String[] args) in C:\Projects\Tests\RethrowExceptions\RethrowExTest\Program.cs:line 44&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;New throw from procedural code loses the line number, as expected&lt;BR&gt;&lt;/STRONG&gt;Inner catch:&lt;BR&gt;Attempted to divide by zero.&lt;BR&gt;&amp;nbsp;&amp;nbsp; at RethrowExTest.Program.Main(String[] args) in C:\Projects\Tests\RethrowExceptions\RethrowExTest\Program.cs:&lt;STRONG&gt;line 60&lt;/STRONG&gt;&lt;BR&gt;Outer catch:&lt;BR&gt;Attempted to divide by zero.&lt;BR&gt;&amp;nbsp;&amp;nbsp; at RethrowExTest.Program.Main(String[] args) in C:\Projects\Tests\RethrowExceptions\RethrowExTest\Program.cs:&lt;STRONG&gt;line 67&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;New throw from method loses the line number, as expected&lt;BR&gt;&lt;/STRONG&gt;Inner catch:&lt;BR&gt;Attempted to divide by zero.&lt;BR&gt;&amp;nbsp;&amp;nbsp; at RethrowExTest.Program.MethodThatThrowsException() in C:\Projects\Tests\RethrowExceptions\RethrowExTest\Program.cs:&lt;STRONG&gt;line 103&lt;/STRONG&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; at RethrowExTest.Program.Main(String[] args) in C:\Projects\Tests\RethrowExceptions\RethrowExTest\Program.cs:line 82&lt;BR&gt;Outer catch:&lt;BR&gt;Attempted to divide by zero.&lt;BR&gt;&amp;nbsp;&amp;nbsp; at RethrowExTest.Program.Main(String[] args) in C:\Projects\Tests\RethrowExceptions\RethrowExTest\Program.cs:&lt;STRONG&gt;line 89&lt;/STRONG&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;How should we design our exception handling, then?&lt;/EM&gt;&amp;nbsp; Follow these 2 simple rules:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;1. If you can reasonably expect any exceptions to be thrown only by methods called from within the try block, you can just call "throw" instead of "throw ex" and retain the debugging info you need.&lt;/STRONG&gt;&amp;nbsp; This is what I explained in the previous article.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;2. If on the other hand there is a substantial probability of the exception being thrown directly from within the try block, you&amp;nbsp;should log the exception's stack trace before you re-throw it.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;P.S. I always welcome comments from knowledgeable readers like "Sanders."&amp;nbsp; Thanks, man!&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=110136"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=110136" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/chrisfalter/aggbug/110136.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Chris Falter</dc:creator>
            <guid>http://geekswithblogs.net/chrisfalter/archive/2007/03/28/110136.aspx</guid>
            <pubDate>Wed, 28 Mar 2007 21:37:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/chrisfalter/comments/110136.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/chrisfalter/archive/2007/03/28/110136.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/chrisfalter/comments/commentRss/110136.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/chrisfalter/services/trackbacks/110136.aspx</trackback:ping>
        </item>
        <item>
            <title>How To: Re-throw an Exception</title>
            <link>http://geekswithblogs.net/chrisfalter/archive/2006/12/07/100601.aspx</link>
            <description>&lt;P&gt;I've coached many youth baseball teams, and I've always put a lot of focus on developing pitchers.&amp;nbsp; Your left fielder can be chasing butterflies, and the right fielder might have his glove off, and the third baseman can be making faces at&amp;nbsp;his sister in the stands...but if the guy on the mound is mowing 'em down, your odds of winning are pretty good.&amp;nbsp; To the uninitiated, pitching looks easy, but in fact it is one of the most difficult skills in all of sports.&amp;nbsp; To throw a baseball with both force and accuracy requires the balance of a dancer on stage, the timing of NASCAR driver weaving through traffic, and the consistency of a pro golfer on the driving range.&amp;nbsp; These do not come easy to a nine year old, so Coach Falter has spent a lot of hours helping aspiring pitchers learn to throw a ball.&lt;/P&gt;
&lt;P&gt;But today Coach Falter is going to explain the secret of catching and throwing something else: an exception.&amp;nbsp; Our first major web project had a lot of exception handling code that looked like this:&lt;/P&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;static&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;void&lt;/FONT&gt;&lt;FONT size=2&gt; Save(QuoteDS dsQuote)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;IDbConnection conn= DataHelper.NewConnection(DataHelper.ConnectionString);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;IDbTransaction trn=&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;null&lt;/FONT&gt;&lt;FONT size=2&gt;;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;try&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;conn.Open();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;trn = conn.BeginTransaction(IsolationLevel.ReadCommitted);&lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// ******************************************************************&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// Do a transacted set of updates, using data in the dataset dsQuote&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// ******************************************************************&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// data update code here...&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// Commit the transaction&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/FONT&gt;&lt;FONT size=2&gt; (trn != &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;null&lt;/FONT&gt;&lt;FONT size=2&gt;)&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;trn.Commit();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;catch&lt;/FONT&gt;&lt;FONT size=2&gt; (&lt;/FONT&gt;&lt;FONT color=#008080 size=2&gt;Exception&lt;/FONT&gt;&lt;FONT size=2&gt; ex)&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/FONT&gt;&lt;FONT size=2&gt; (trn != &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;null&lt;/FONT&gt;&lt;FONT size=2&gt;)&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;trn.Rollback();&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&lt;/FONT&gt;&lt;FONT size=2&gt; ex;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;finally&lt;/FONT&gt;&lt;FONT size=2&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;conn.Dispose();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;}&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;!--EndFragment--&gt;This code needs an exception handler&amp;nbsp;in order to&amp;nbsp;rollback any in-flight transaction.&amp;nbsp; On the other hand, it needs to rethrow the exception so that a handler&amp;nbsp;further down the stack can catch it, log it, and display an appropriate message to the user.&amp;nbsp; This is the exception-handling pattern blessed by Microsoft for all non-masochistic programmers.&amp;nbsp; (Masochistic programmers prefer to set up exception handlers in every function, and build an elaborate scheme of return codes and switch statements and Lord knows what else.)&lt;/P&gt;
&lt;P&gt;However, the above code has a hidden flaw.&amp;nbsp; I'll grab a cup of coffee while you examine the code carefully....&lt;/P&gt;
&lt;P&gt;Okay, you've been patient enough, it's time for your reward.&amp;nbsp; When the .NET Framework executes this statement:&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&lt;/FONT&gt; ex;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;it throws away all the stack information above the current function.&amp;nbsp; So when you look at your error&amp;nbsp;log, you won't know which line of code was executing when the exception was thrown.&amp;nbsp; Sometimes this won't be a bother, but other times you will spend fruitless hours speculating on what might have happened.&amp;nbsp; So we need a better approach.&lt;/P&gt;
&lt;P&gt;Here's how you retain the full stack trace: just rethrow the exception like this...&lt;/P&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT color=#0000ff&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;throw&lt;/FONT&gt;;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;That's right, all you need to do is remove one little word.&amp;nbsp; Superficially, it is no more different from "throw ex" than the throwing motions on a change-up&amp;nbsp;and a fastball.&amp;nbsp;&amp;nbsp;(Hint: they are supposed to be identical; the difference is in how the pitcher holds the ball.)&amp;nbsp; But like the difference between a fastball and a change-up, the difference between "throw" and "throw ex" becomes obvious very quickly!&amp;nbsp; So get out those code editors and start throwing like you're supposed to...and lift your knee almost up to your elbow during the wind-up....and step toward home plate....&lt;/P&gt;
&lt;P&gt;EDIT 3/28/2007: Based on a reader's comment and further research, I have updated my advice.&amp;nbsp; See "&lt;A href="http://geekswithblogs.net/chrisfalter/archive/2007/03/28/110136.aspx"&gt;More on How To Re-throw an Exception&lt;/A&gt;" for the latest and greatest.&lt;/P&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=100601"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=100601" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/chrisfalter/aggbug/100601.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Chris Falter</dc:creator>
            <guid>http://geekswithblogs.net/chrisfalter/archive/2006/12/07/100601.aspx</guid>
            <pubDate>Fri, 08 Dec 2006 00:31:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/chrisfalter/comments/100601.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/chrisfalter/archive/2006/12/07/100601.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/chrisfalter/comments/commentRss/100601.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/chrisfalter/services/trackbacks/100601.aspx</trackback:ping>
        </item>
        <item>
            <title>Visual Studio Team Server, the Gangly Adolescent</title>
            <link>http://geekswithblogs.net/chrisfalter/archive/2006/08/24/89239.aspx</link>
            <description>&lt;P&gt;As a high school sophomore I was 6'1&amp;#8220; tall and 140 pounds--a human bean pole.&amp;nbsp; My arms shot out of my sleeves like beanstalks in Jack's garden.&amp;nbsp; You could practically see my ankles emerging from the bottom of blue jeans as I stood before you.&amp;nbsp; As a physical specimen, though, you could see on my frame what I would eventually become as an adult, after a little more maturation.&amp;nbsp; I was a gangly adolescent.&lt;/P&gt;
&lt;P&gt;I'm almost delirious that Microsoft finally released Visual Studio Team Server (VSTS), especially with its new source control solution.&amp;nbsp; Lord have mercy on the soul of the librarian who ever attempted to manage source code for a large team using Visual SourceSafe!&amp;nbsp; When I was Microsoft's manager of support for a large&amp;nbsp;ISV, I routinely fielded complaints about VSS: corrupted source databases, weekend-long maintenance routines that would blow up at the end and leave a team stranded, etc.&amp;nbsp; So even though it's a brand-new product, VSTS already exhibits the features that make it worth the migration effort.&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;As a brand-new product, though, VSTS is&amp;nbsp;a gangly adolescent. And like the teenage version of Chris Falter,&amp;nbsp;VSTS has&amp;nbsp;some&amp;nbsp;awkwardness and&amp;nbsp;blemishes.&amp;nbsp; I ran across one today.&amp;nbsp; As I was adding a project to my solution from source control, I accidentally chose to place it in a folder that already had a project.&amp;nbsp; As expected, VS displayed an error message: &lt;/P&gt;
&lt;P&gt;&lt;EM&gt;The folder 'x' cannot be used for the solution or project you are trying to open because it is already in use to store part of another solution or project.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;Okay, let's close the error dialog and try again.&amp;nbsp; File menu, source control, add project from source control, choose the same project, and...oh, oh, a pimple.&amp;nbsp; The &amp;#8220;local path&amp;#8221; text box is disabled.&amp;nbsp; There is no apparent means of changing the path to a different folder.&amp;nbsp; When I click OK, I get the same result, of course.&amp;nbsp; Same folder, same error message.&amp;nbsp; I'm stuck, stuck, stuck.&amp;nbsp; If the interface to change the local path is disabled, how am I going to add the project?&lt;/P&gt;
&lt;P&gt;After the usual googling, head-scratching, and oath-muttering, I discovered that the Team Server&amp;nbsp;Source Control Explorer manages the mapping between projects and file paths.&amp;nbsp; So:&lt;/P&gt;
&lt;P&gt;1. Open Source Control Explore (View &amp;gt; Other Windows &amp;gt; Source Control Explorer).&lt;/P&gt;
&lt;P&gt;2. Choose Workspaces... in the Workspace dropdown.&lt;/P&gt;
&lt;P&gt;3. Select your workspace and click the Edit button.&lt;/P&gt;
&lt;P&gt;4. Either remove the working folder for the project so that you can start over, or edit its &amp;#8220;Local Folder&amp;#8221; right there in the grid control.&amp;nbsp; I chose to edit the Local Folder in the grid control.&lt;/P&gt;
&lt;P&gt;5. Try again, and dance triumphantly, like John Travolta.&lt;/P&gt;
&lt;P&gt;Hopefully the adult version of VSTS that eventually emerges will be smart enough not to create a mapping if the attempt to add a project fails.&amp;nbsp; In the meanwhile, maybe this posting will help a few developers avoid some of the anguish of adolescence.&lt;/P&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=89239"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=89239" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/chrisfalter/aggbug/89239.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Chris Falter</dc:creator>
            <guid>http://geekswithblogs.net/chrisfalter/archive/2006/08/24/89239.aspx</guid>
            <pubDate>Fri, 25 Aug 2006 04:44:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/chrisfalter/comments/89239.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/chrisfalter/archive/2006/08/24/89239.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/chrisfalter/comments/commentRss/89239.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/chrisfalter/services/trackbacks/89239.aspx</trackback:ping>
        </item>
        <item>
            <title>The Literary Ambitions of the ASP.NET 2.0 Site Compiler</title>
            <link>http://geekswithblogs.net/chrisfalter/archive/2006/04/28/76685.aspx</link>
            <description>&lt;P&gt;In previous versions,&amp;nbsp;ASP.NET considered&amp;nbsp;the web.config file to be untouchable.&amp;nbsp; What you, the developer, wrote into the file may as well have been engraved like the Ten Commandments into stone tablets.&amp;nbsp; But under the new compilation model, ASP.NET wants to collaborate with you in authoring the web.config file.&amp;nbsp; Specifically, during site compilation, it will insert &lt;ADD assembly ...&gt;lines into the /configuration/system.web/compilation/assemblies element to make sure that the runtime JIT compiler knows how to link to the dependencies of project references.&amp;nbsp; In other words, it will enumerate the entire dependency tree and write the necessary metadata to make sure that the JIT compiler knows what it needs, if you have not already provided the information via an explicit reference.&lt;/P&gt;
&lt;P&gt;We stumbled onto this behavior quite by accident.&amp;nbsp; For no obvious reason, when we ran our build script to compile/deploy a new website, the Visual Studio 2005 compiler decided to sneak these lines into the web.config:&lt;/P&gt;
&lt;DIV style="FONT-SIZE: 9pt; FONT-FAMILY: monospace; BACKGROUND-COLOR: white"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;add&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;assembly&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;stdole, Version=7.0.3300.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;/&amp;gt;&lt;BR&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;add&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;assembly&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Office, Version=7.0.3300.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;/&amp;gt;&lt;BR&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;add&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;assembly&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;/&amp;gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;P&gt;And VS 2005 was quite insistent about adding these lines:&amp;nbsp;it actually removed the read-only attribute from web.config, inserted the lines, and continued on its merry way.&amp;nbsp; We, of course, knew nothing about the compiler's silent literary ambitions, so the site deployed as usual.&amp;nbsp; But then it blew up; we did not have the stdole and Office assemblies version 7.0.3300.0 installed on the web farm, so things went south very quickly.&amp;nbsp; The event log recorded something like this:&lt;/P&gt;&lt;SPAN id=_ctl0_MainContent_PostFlatView&gt;&lt;SPAN&gt;
&lt;H2&gt;&lt;FONT size=2&gt;&lt;I&gt;Configuration Error&lt;/I&gt; &lt;/FONT&gt;&lt;/H2&gt;
&lt;P&gt;&lt;FONT size=2&gt;&lt;FONT face="Arial, Helvetica, Geneva, SunSans-Regular, sans-serif "&gt;&lt;B&gt;Description: &lt;/B&gt;An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately. &lt;BR&gt;&lt;BR&gt;&lt;B&gt;Parser Error Message: &lt;/B&gt;Could not load file or assembly 'stdole, Version=7.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;P&gt;Googling turned up&amp;nbsp;&lt;A href="http://www.thescripts.com/forum/thread465826.html"&gt;a thread&lt;/A&gt; where a developer declared that the problem could be solved by changing the default html editor on the build machine.&amp;nbsp; This did not work for us.&amp;nbsp; Then I noticed that one of my colleagues had recently added a new reference in one of the projects that was in the site project reference list.&amp;nbsp;&amp;nbsp;In other words, after my colleague's modification, we could now draw a line indirectly from the site to the stdole and Office assemblies: (1)&amp;nbsp;site references a project, (2) the project references&amp;nbsp;the Dart.PowerWEB.LiveControls component, and (3) Dart.PowerWEB.LiveControls references the stdole and Office assemblies.&lt;/P&gt;
&lt;P&gt;We had not noticed this prior to deployment because the Dart development suite&amp;nbsp;had installed the assemblies on the test sites' host server.&amp;nbsp; Of course, the Dart run-time environment on the production server farm did NOT install the assemblies.&amp;nbsp; Shame on you, Dart!&amp;nbsp; After we removed the Dart.PowerWEB.LiveControls reference from the project, ASP.NET lost its literary ambitions.&amp;nbsp; And not a moment too soon; next thing you know, the compiler will start a blog.&amp;nbsp; And I don't want to have to compete with Microsoft technology!&lt;/P&gt;
&lt;P&gt;So if you notice the new literary ambitions of the ASP.NET compiler, and they suddenly&amp;nbsp;mess&amp;nbsp;with your deployment, you know what to do: examine any references you recently added to&amp;nbsp;the site's dependency tree, because one of them is the source of your problem.&amp;nbsp; Keep removing references until ASP.NET ends its crazy literary ambitions.&amp;nbsp; There are enough authors and bloggers in the world already; we don't need ASP.NET to join the crowd.&lt;/P&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=76685"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=76685" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/chrisfalter/aggbug/76685.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Chris Falter</dc:creator>
            <guid>http://geekswithblogs.net/chrisfalter/archive/2006/04/28/76685.aspx</guid>
            <pubDate>Sat, 29 Apr 2006 01:39:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/chrisfalter/comments/76685.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/chrisfalter/archive/2006/04/28/76685.aspx#feedback</comments>
            <slash:comments>11</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/chrisfalter/comments/commentRss/76685.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/chrisfalter/services/trackbacks/76685.aspx</trackback:ping>
        </item>
        <item>
            <title>Exceeding the Wildest Dreams of the Microsoft Marketing Department</title>
            <link>http://geekswithblogs.net/chrisfalter/archive/2006/04/21/75814.aspx</link>
            <description>&lt;P&gt;The marketing gurus at Microsoft singlehandedly support a half dozen Starbucks franchises, no doubt, as they prime their adrenaline pumps to concoct Yet Another Plug (YAP) for the virtues of the .NET Framework.&amp;nbsp; "Write more functionality with 80% less code!", they shout.&amp;nbsp; As a heartfelt idealist, I take these claims seriously, so I have been looking for evidence to support the yapping.&amp;nbsp; Recently, I achieved a wondrous breakthrough that will cheer the Redmond lads and lassies and leave the Java crowd groaning in dismay.&amp;nbsp; Yes, folks, with exactly ZERO lines of code I have produced a programming construct that formerly required at least a few lines of procedural code.&amp;nbsp; And I am proud to say that it is a record that will never be broken; no one will ever create the same programming construct with less than zero lines of code, right?&lt;/P&gt;
&lt;P&gt;Sidestep coding a data tier by binding SQL statements directly to a DataGridView control: that's pretty swift.&amp;nbsp; (Although for non-trivial applications I would not recommend it; I'll leave the details for another post.)&amp;nbsp; Avoid writing a WSDL interface for a web service by decorating a plain old programming interface with attributes and running a WSDL generation tool: what a concept!&amp;nbsp; But it takes genius, my friends-- yes, pure, unadulterated genius--to bequeath to the world a framework that allows the cunning programmer to create an infinite loop without any code whatsoever.&amp;nbsp; An infinite loop, effortlessly created with no code: who knew?&lt;/P&gt;
&lt;P&gt;In the days before the .NET Framework, the tool-deprived, hard-working programmer actually had to write code to create an infinite loop.&amp;nbsp; Here's an interesting example from C++, which is of course the language in which all the Windows operating systems are written:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" color=#000080 size=2&gt;void RunLoop() {&lt;BR&gt;&amp;nbsp; int i;&lt;BR&gt;&amp;nbsp; i = 10;&lt;BR&gt;&amp;nbsp; while (i &amp;gt; 0) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; i = i--;&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;&amp;nbsp; return;&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;So how is this an infinite loop?&amp;nbsp; You just decrement i until it reaches 0, then you break out of the while loop, right?&amp;nbsp; Ha!&amp;nbsp; &amp;#8220;i--&amp;#8221; really means &amp;#8220;i = i-1&amp;#8221;, and it returns the &lt;EM&gt;pre-decrement&lt;/EM&gt; value of i.&amp;nbsp; So when you assign i-- to i&amp;nbsp;&lt;EM&gt;&amp;nbsp;the value of i never changes&lt;/EM&gt;, and you just keep looping and looping and looping.&amp;nbsp; Doesn't this make you long for the good old days of C++, when you could write obscure bugs like this, or do pointer math that would&amp;nbsp;allow you to&amp;nbsp;modify data&amp;nbsp;who-knows-where in the heap?&amp;nbsp; Of course, if you worked at Microsoft, you wouldn't have to long for the good old days, you could still be living them as you worked on Windows.&amp;nbsp; And you wondered why they have all those security bugs.&lt;/P&gt;
&lt;P&gt;Now, though, the .NET-equipped, lazy programmer can write an infinite loop with no code at all and head home early.&amp;nbsp; Here's how:&lt;/P&gt;
&lt;P&gt;1. Write an ASP.NET 2.0 application.&amp;nbsp; Configure the customErrors node in your web.config to redirect to an error page.&lt;/P&gt;
&lt;DIV style="FONT-SIZE: 9pt; FONT-FAMILY: monospace; BACKGROUND-COLOR: white"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;configuration&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV style="FONT-SIZE: 9pt; FONT-FAMILY: monospace; BACKGROUND-COLOR: white"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;system.web&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/DIV&gt;&lt;SPAN style="COLOR: blue"&gt;
&lt;DIV style="FONT-SIZE: 9pt; FONT-FAMILY: monospace; BACKGROUND-COLOR: white"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;customErrors&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;mode&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;On&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;defaultRedirect&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;Error.htm&lt;/SPAN&gt;&lt;SPAN style="COLOR: black"&gt;"&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;/&amp;gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV style="FONT-SIZE: 9pt; FONT-FAMILY: monospace; BACKGROUND-COLOR: white"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp; &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;system.web&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/DIV&gt;
&lt;DIV style="FONT-SIZE: 9pt; FONT-FAMILY: monospace; BACKGROUND-COLOR: white"&gt;
&lt;DIV style="FONT-SIZE: 9pt; FONT-FAMILY: monospace; BACKGROUND-COLOR: white"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: maroon"&gt;configuration&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;BR&gt;&lt;/SPAN&gt;&lt;/DIV&gt;&lt;BR&gt;&lt;/DIV&gt;&lt;/SPAN&gt;
&lt;P&gt;2. Put frames in error.htm, and let each frame contain an aspx page.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;3. Make a deployment error that causes all the aspx pages to break.&amp;nbsp; You could forget, for example,&amp;nbsp;to tell your admin that the site is configured to JIT-compile the DLLs dynamically, and let him xcopy code-behind DLLS to the production website.&lt;/P&gt;
&lt;P&gt;4. Pop open a frosty beverage and watch the fun when&amp;nbsp;ASP.NET doesn't know how to deal with the multiple copies of the same class in the AppDomain.&amp;nbsp; It will&amp;nbsp;detect an error on the home page, then redirect&amp;nbsp;the browser to error.htm, just like the web.config tells it to.&amp;nbsp; The browser&amp;nbsp;will then try to load aspx pages,&amp;nbsp;and then ASP.NET will&amp;nbsp;detect&amp;nbsp;more errors and&amp;nbsp;redirect the browser&amp;nbsp;to error.htm again, so the browser will request the framed aspx pages again, which will cause ASP.NET to detect more errors &lt;EM&gt;yet&lt;/EM&gt; &lt;EM&gt;again&lt;/EM&gt; and redirect the browser to error.htm &lt;EM&gt;yet&lt;/EM&gt; &lt;EM&gt;again&lt;/EM&gt;,&amp;nbsp;and so forth.&amp;nbsp; Just watch the status bar&amp;nbsp;flash text like an old-timey stock ticker!&amp;nbsp; You never had such fun in the Pleistocene pre-.NET days.&lt;/P&gt;
&lt;P&gt;If you want to spoil the fun and make things actually work, I would recommend that your user-friendly error.htm page never contain any .NET dependencies.&amp;nbsp; It should be pure browser-readable code; IIS should be able to pass it to the browser as is, without&amp;nbsp;invoking&amp;nbsp;anything related to the&amp;nbsp;.NET Framework.&amp;nbsp; Of course, you could always ignore this advice in an attempt&amp;nbsp;to tie my record for fewest lines of code to create an infinite loop.&amp;nbsp; But I'm not worried; I've created a record that can never be broken!&lt;/P&gt;
&lt;P&gt;Here's hoping that the Microsoft marketing folks read this blog and get so excited that they storm the nearest Starbucks and run up a massive tab.&lt;/P&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=75814"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=75814" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/chrisfalter/aggbug/75814.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Chris Falter</dc:creator>
            <guid>http://geekswithblogs.net/chrisfalter/archive/2006/04/21/75814.aspx</guid>
            <pubDate>Fri, 21 Apr 2006 19:07:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/chrisfalter/comments/75814.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/chrisfalter/archive/2006/04/21/75814.aspx#feedback</comments>
            <slash:comments>6</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/chrisfalter/comments/commentRss/75814.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/chrisfalter/services/trackbacks/75814.aspx</trackback:ping>
        </item>
        <item>
            <title>VS 2005 Gotcha: Project Loading When Opening Solution from Source Control</title>
            <link>http://geekswithblogs.net/chrisfalter/archive/2006/04/03/74191.aspx</link>
            <description>&lt;P&gt;We have invested a lot of effort into making the file paths for our projects mirror the SourceSafe project hierarchy, per the &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/tdlg_rm.asp"&gt;long-standing Microsoft&amp;nbsp;&amp;#8220;Team Development&amp;#8221; whitepaper&lt;/A&gt;&amp;nbsp;(especially &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/tdlg_ch3.asp"&gt;chapter 3&lt;/A&gt;).&amp;nbsp; The initial solution developer, typically the team lead, creates a blank Visual Studio solution, then adds the various projects at the solution root.&amp;nbsp;&amp;nbsp;To illustrate, here's the&amp;nbsp;directory structure&amp;nbsp;from a solution I created recently:&lt;/P&gt;
&lt;DIV&gt;&lt;A style="border-size: 0px" href="/chrisfalter/gallery/image/1992.aspx" target=_blank&gt;&lt;IMG alt="Directory Structure" src="/images/geekswithblogs_net/chrisfalter/4298/o_Sample_Folder_Structure.JPG" align=middle&gt; &lt;/A&gt;&lt;/DIV&gt;
&lt;P&gt;After the solution is checked in to source control, the project hierarchy in SourceSafe will mirror the file directory structure:&lt;/P&gt;
&lt;DIV&gt;&lt;A style="border-size: 0px" href="/chrisfalter/gallery/image/1993.aspx" target=_blank&gt;&lt;IMG alt="SourceSafe Project Hierarchy" src="/images/geekswithblogs_net/chrisfalter/4298/o_Sample_Project_Hierarchy.JPG" align=middle&gt; &lt;/A&gt;&lt;/DIV&gt;
&lt;P&gt;Any subsequent developer who opens the solution will find that its projects are all &amp;#8220;auto-magically&amp;#8221; loaded at the correct file path.&amp;nbsp; Hence all developers who work on the solution will share the same file directory structure, and painless collaboration is assured.&amp;nbsp; (Except for the weekly project management meetings...)Yes, you have entered programming heaven.&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Unless St. Peter notices you're using Visual Studio 2005, in which case he bars you at the gate.&lt;/P&gt;
&lt;P&gt;Try opening someone else's solution in VS 2005, and you'll find your projects being loaded in a location like &lt;STRONG&gt;C:\Documents and Settings\MyUserName\My Documents\Visual Studio 2005\Projects\Projects\Dev\Utils\etcetera&lt;/STRONG&gt;.&amp;nbsp; Argh!&amp;nbsp; What happened?&lt;/P&gt;
&lt;P&gt;After a bit of IDE spelunking, I&amp;nbsp;opened this little dialog from the Tools&amp;nbsp;=&amp;gt; Options menu:&lt;/P&gt;
&lt;DIV&gt;&lt;A style="border-size: 0px" href="/chrisfalter/gallery/image/1990.aspx" target=_blank&gt;&lt;IMG alt="Tools Options Default" src="/images/geekswithblogs_net/chrisfalter/4298/o_Default%20Project%20Path.JPG" align=middle&gt;&lt;/A&gt;&lt;/DIV&gt;
&lt;P&gt;So you&amp;nbsp;see, Visual Studio 2005 believes that you &lt;STRONG&gt;want&lt;/STRONG&gt; to load all projects into the default VS projects location, regardless of&amp;nbsp;what your source-controlled solution file might say to the contrary.&amp;nbsp;And if you've redirected your &amp;#8220;My Documents&amp;#8221; folder to a network drive so your IT department will back it up daily, the way I have, VS 2005 will be polite enough to tell you that code access permissions will prevent you from running your code.&amp;nbsp; Oh, how kind!&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Fortunately, this problem is not too hard to fix.&amp;nbsp; Just change the default location to a root directory...&lt;/P&gt;
&lt;DIV&gt;&lt;A style="border-size: 0px" href="/chrisfalter/gallery/image/1991.aspx" target=_blank&gt;&lt;IMG alt="Tools Options Correct Setting" src="/images/geekswithblogs_net/chrisfalter/4298/o_Corrected%20Project%20Path.JPG" align=middle&gt;&lt;/A&gt;&lt;/DIV&gt;
&lt;P&gt;...and St. Peter will let you pass through the pearly programming gates.&lt;/P&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=74191"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=74191" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/chrisfalter/aggbug/74191.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Chris Falter</dc:creator>
            <guid>http://geekswithblogs.net/chrisfalter/archive/2006/04/03/74191.aspx</guid>
            <pubDate>Tue, 04 Apr 2006 00:36:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/chrisfalter/comments/74191.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/chrisfalter/archive/2006/04/03/74191.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/chrisfalter/comments/commentRss/74191.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/chrisfalter/services/trackbacks/74191.aspx</trackback:ping>
        </item>
    </channel>
</rss>