This post is a complete geek-tangent, so if you’re a non-developer excuse me for the next three and a half minutes.
A Nasty .NET Constants “Bug”
Two days ago we ran into one of the nastiest bugs I’ve seen in many moons. With large systems I’ve found that bugs in code are the relatively easy to fix, while bugs with deployment, configuration files, connectivity and the Global Assembly Cache (GAC – a folder where .NET apps can store shared assemblies) are just plain nasty. They’re hard to reproduce, hard to troubleshoot (there’s no “step-through debugging” when you’re trying to connect to a partner’s web service), and generally eat up a ton of time.
Here’s the problem we recently encountered:
We have an assembly that’s used by 12 applications, let’s call it “constants,” that holds authentication credentials (username/password) that to login to a web service. We deployed the 12 apps and the constants assembly to a QA server and everything ran smoothly. Several months later we needed to a) point our apps to a different version of the web service and b) update the authentication credentials. After making a change to our global config file to re-point our apps, we deployed a new version of constants with the updated credentials. Upon firing everything up we received “401: Unauthorized” errors.
After a day and a half of troubleshooting Jeremy found this article that talks about how .NET constants are compiled into external assemblies. So although the constants assembly is referenced at compile time, it does not exist after that. This makes sense if you think about it; constants shouldn’t change, and hard-coding the constant values into the calling assemblies is certainly a performance gain. But when you’re in the midst of a deployment, this is not the first behavior that comes to mind.
Our workaround? As the article discusses, we used “static readonly” in place of “const.” We’ll take a very slight performance hit, but gain the functionality we’re looking for.
Another Nasty One – .NET Web Services and the Word “Specified”
While I’m on the subject of weird .NET bugs, did you know if you have a boolean web service parameter with the word “Specified” at the end of it and you add a web reference to it, that Microsoft will add a second version of the same parameter with a “1” tagged on? An example:
Create a web service method with the following signature:
public string DoStuff(string firstName, bool firstNameSpecified)
When you add a web reference to it, your proxy class signature will be:
public string DoStuff(string firstName, [System.Xml.Serialization.XmlElementAttribute(“firstNameSpecified”)] bool firstNameSpecified1)
I’ve been unable to find an explanation for this behavior, but I’m sure it’s a side effect of some deep, dark secret well-hidden in the .NET framework.
Our workaround? Use the word “Provided” instead of “Specified.”
Sometimes a high-tech problem requires a low-tech hack.