Consider that the built in localization support of the ASP.NET framework is awesome.
By storing the files in the /App_GlobalResources folder I get strongly typed objects to set my labels like this:
litHeading.Text = BlogResources.BlogCategoriesLabel;
I don't have to do anything to make it localize, by default the thread will execute as the culture specified in the browser preferred language and it will automatically choose the correct .resx file if it exists (or by config settings you can force it to execute as a specific culture), so if my browsert is set to de-DE for German and BlogResources.de.resx exists it will use that and if the key "BlogCategoriesLabel" does not exist in that file it will fall back to the default English file. I get all that for free, no hunting around the file system no checking for missing files or keys needed in my code and the key must exist in the defualt file for it to compile so errors are avoided.
Similarly there is a databinding syntax like this:
<asp:DropDownList ID="ddGMapType" runat="server" EnableTheming="false" CssClass="forminput">
<asp:ListItem Value="G_NORMAL_MAP" Text="<%$ Resources:Resource, GoogleNormalMap %>" />
<asp:ListItem Value="G_SATELLITE_MAP" Text="<%$ Resources:Resource, GoogleSatelliteMap %>" />
<asp:ListItem Value="G_HYBRID_MAP" Text="<%$ Resources:Resource, GoogleHybridMap %>" />
<asp:ListItem Value="G_PHYSICAL_MAP" Text="<%$ Resources:Resource, GoogleTerrainMap %>" />
</asp:DropDownList>
again I don't have to do anything extra to make it localize.
Now do I want to throw that away and build my own thing that I have to support? NO!!!! That would be a lot of work and a huge re-write of good solid working code.
But on a case by case basis I'm willing to do things like this:
if (displaySettings.OverrideCategoryLabel.Length > 0)
{
litHeading.Text = displaySettings.OverrideCategoryLabel;
}
else
{
litHeading.Text = BlogResources.BlogCategoriesLabel;
}