If you log exceptions, watch out for Response.Redirect() – level 200

A common practice with any web application is to log fatal exceptions.  After all, if the user can’t complete the intended operation, wouldn’t you want to know about it?  I log all fatal exceptions in my apps because if one of these happens, I want to know about it so I can fix the bug.  Often, a production environment will uncover bugs in fringe use cases — bugs that would never turn up in the normal test cycle.  The exception information can help you reproduce and fix the bug.

Recently I employed the use of Response.Redirect( ) for a situation where I wanted to stop doing the work on the current page and go to another that was dependent on the query string.  I used Response.Redirect( ) for this, and my exception log started growing.  After investigation, I found that a ThreadAbortException was being thrown with every Response.Redirect( ) call.  By looking at the call stack, I discovered that Response.Redirect( ) actually calls Response.End( ) internally.  Response.End( ) throws the ThreadAbortException to terminate work on the current thread after sending the redirect message.


The elusive Path class and it’s “hidden” static methods – level 200

If you ever find yourself manually parsing a file name or any part of a path, stop!  It’s very tempting to use a couple of lines of code to trim an extension off of a file, but why do it.  Also, if you ever have a directory path and a file name, don’t concatenate the two strings together (making sure that a “/” is in between), us Path.Combine instead.  I think that a lot of code can be reduced by reusing the BCL.  Every now and then you might save 15 minutes by taking 5 minutes to research what is available in the BCL. 

Let’s take a look at the System.IO.Path class and see what it can do for us.  Just by looking at the following method names, I’m sure you can figure out how to use them to reduce your codebase:

Public Fields

public fieldstatic (Shared in Visual Basic)AltDirectorySeparatorChar

Supported by the .NET Compact Framework.

Provides a platform-specific alternate character used to separate directory levels in a path string that reflects a hierarchical file system organization.
public fieldstatic (Shared in Visual Basic)DirectorySeparatorChar

Supported by the .NET Compact Framework.

Provides a platform-specific character used to separate directory levels in a path string that reflects a hierarchical file system organization.
public fieldstatic (Shared in Visual Basic)InvalidPathChars

Supported by the .NET Compact Framework.

Provides a platform-specific array of characters that cannot be specified in path string arguments passed to members of the Path class.
public fieldstatic (Shared in Visual Basic)PathSeparator

Supported by the .NET Compact Framework.

A platform-specific separator character used to separate path strings in environment variables.
public fieldstatic (Shared in Visual Basic)VolumeSeparatorChar

Supported by the .NET Compact Framework.

Provides a platform-specific volume separator character.

Public Methods

public methodstatic (Shared in Visual Basic)ChangeExtension

Supported by the .NET Compact Framework.

Changes the extension of a path string.
public methodstatic (Shared in Visual Basic)Combine

Supported by the .NET Compact Framework.

Combines two path strings.
public methodstatic (Shared in Visual Basic)GetDirectoryName

Supported by the .NET Compact Framework.

Returns the directory information for the specified path string.
public methodstatic (Shared in Visual Basic)GetExtension

Supported by the .NET Compact Framework.

Returns the extension of the specified path string.
public methodstatic (Shared in Visual Basic)GetFileName

Supported by the .NET Compact Framework.

Returns the file name and extension of the specified path string.
public methodstatic (Shared in Visual Basic)GetFileNameWithoutExtension

Supported by the .NET Compact Framework.

Returns the file name of the specified path string without the extension.
public methodstatic (Shared in Visual Basic)GetFullPath

Supported by the .NET Compact Framework.

Returns the absolute path for the specified path string.
public methodstatic (Shared in Visual Basic)GetPathRoot

Supported by the .NET Compact Framework.

Gets the root directory information of the specified path.
public methodstatic (Shared in Visual Basic)GetTempFileName

Supported by the .NET Compact Framework.

Returns a uniquely named zero-byte temporary file on disk and returns the full path to that file.
public methodstatic (Shared in Visual Basic)GetTempPath

Supported by the .NET Compact Framework.

Returns the path of the current system’s temporary folder.
public methodstatic (Shared in Visual Basic)HasExtension

Supported by the .NET Compact Framework.

Determines whether a path includes a file name extension.
public methodstatic (Shared in Visual Basic)IsPathRooted Gets a value indicating whether the specified path string contains absolute or relative path information.

Evaluating CommunityServer RC1 – level 000

I downloaded CommunityServer RC1 today, and it looks promising.  Setup was a snap.  The installer is great.  I went through the forums, blogs, and gallery features, and it looks very good.  I love the photo gallery feature.  This is some really great UI work!  The blog part looks very similar to .Text v0.95, but the admin section has been really beefed up.  There are a lot more settings:  comment moderation, publish date, show post on main feed, etc. 

I also like it that every screen has been made a control, so even though it’s distributed with .aspx pages, I can concieve an easier integration into an existing site by putting the CS controls in already existing pages.

I predict that current .Text sites will upgrade to this and facilitate an even more productive community where each member can have a small part of it to call home for not only the online journal(blog) but also a photo album.

Great work, Telligent!

Use Master pages in v1.1 – level 200

Ben Reichelt blogged about using Master Pages, and I realized that I never put out the word that I posted my version of v1.1 master page controls to my website.

Go to http://palermo.cc/MyToolDownloads/Default.aspx to download my “EZ Master Pages” controlset.  It is based on the foundation of the controls from Paul Wilson, but I’ve made significant improvements including programmatically setting and changing the master as well as facilitating nested masters.  My controlset follows the pattern of 2.0 closely, so you will have a very easy migration path with these controls.


I’m famous. I guest-starred in a TestFixture on a Whidbey webcast! – level 000

Rory Blyth gave a webcast on the unit-testing features of Whidbey, and he mentioned my name in the test.  I’m flattered.  I will completely ignore that “Jeremey Palermo” was mentioned.  I’ll assume it was “Jeffrey Palermo” and go on with life. 🙂

The recorded webcast can be viewed at http://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032267323&EventCategory=5&culture=en-US&CountryCode=US

Go to 29 minutes into the presentation, and you’ll hear where Rory introduces me.  Then go to 38:40 in the presentation, and that’s where he corrects my first name. 🙂

Thanks Rory (if you are reading this).

Don’t use public const EVER (if you want maintainable code) – level 200

The c# const keyword is great.  At compile time, the contant is actual replaced by the actual string anywhere that the constant is referenced.  The compiler just does a find/replace.  This is great for private and internal constants.  If ever the constant changes (and it might), it’s replaced when the assembly is rebuilt.  If you use the contant 50 times in your code.  Use Lutz Roeder’s Reflector to look at one of your assemblies that references these contants.  You won’t find the constant name.   You will actually find the string that the constant was set to.  This is the optimization benefit fo constants. 

Now, what happens when you have a public constant, and you reference it from a client assembly?  Same thing.  The compiler takes the value of the constant and replaces it with the literal string.  100% optimized.  Then, a new version of the shared assembly comes out, and the constant has changed.  You drop this new assembly in your app directory and try your application.  No dice.  Your assembly has the old constant string hard-coded in it.  The shared assembly is expecting the new string.  Bad situation.  You have to recompile the client assembly (hoping that the 5-year old source code is the right copy and that things weren’t misplaced over the years) and completely retest the new build (the cost of that depending on the size of the application).

The good news is that there is a very easy way to prevent this maintenance nightmare:  don’t use public constants.  Instead, use public static readonly varName.  This is a normal variable with the same scope as a public const, but client assemblies reference the variable instead of replacing it with the literal string.  Now when the const changes, the client assembly gets the new string through the public static variable.

It only takes a minute to do a global search for “public const” to see if your application might fall prey to this problem.  Also, be sure to convert protected constants as well because client assemblies could contain classes that derive from the offending class.

I’ve been accused of being a “purist” – is that a compliment – level 100

At work, I’ve suggested code changes such as not hard-coding any strings at
all (making them config items or string constants), and I’ve been indirectly
accused of being a purist.  Not really knowing whether that is a good or bad
thing (if that actually means leaning to an extreme), I looked it up.  Dictionary.com says:

“One who practices or urges strict correctness, especially in the use of
words.” and

“someone who insists on great precision and correctness.”

Search google for “purist” and c#, and you’ll find more than 2000 results. 
That tells me that this is a well-used word in the .Net world.  The question
is:  Is being a purist a good or bad thing?

I believe that urging strict correctness is a good thing.  Obviously, my
application of this would be in writing code for the .Net framework.  If I don’t
use strict correctness, then I may be coding incorrectly, and that would be bad;
therefore, I would say that it is a good thing to be a .Net purist:  urging
strict correctness:  wanting all code to be completely correct.  Then we have to
define correct because that is really where the debate is.  What is the correct
way to code.  After we define that, I think everyone would want to be correct,
but people bicker over what method is “correct” *Sigh*. 

To be a purist, I would think that I would have to be very knowledgable in my
field to be able to demonstrate and prove a correct method against an incorrect

I could go further by saying that if you aren’t a purist and don’t insist on
precision and correctness, then there is another continuum toward the other
extreme of completely sloppy.

At this point in this written conversation with myself, I have identified a
range of coding methods with one extreme being totally correct and the other
extreme being totally sloppy.  I ask myself, can I be totally correct all the
time?  Obviously I look at code written last year and can see mistakes or parts
that could be made better, or more correct.  So, then, I can conclude that given
my present knowledge of my chosen platform, I must strive to be as correct as
possible with my goal of having 100% correct code.  I don’t think I’ll ever
achieve it, but to be a coding purist is a good thing, and I will strive always
to think as one.

Shutdown Server 2003 without giving a reason – level 200

I also use Server 2003 on my laptop as my main OS.  Since all my apps will run
on this OS, why not develop on it?  Sahil has really hit a home run with this
blog post about disabling the shutdown reason dialog.  I know, group policy.  It
controls everything, but I just don’t ever go mucking around with those settings
because I don’t have a need to, but check it out below:

Windows 2003 Shutdown “Enter Reason” dialog