The other day while working on some code for a client I was unexpectedly bitten by a bad practice that programming books from my childhood warned me about - a global variable broke my code. Well kind of, anyway. I was trying to automate a configuration change to to an Office365 group and after consulting the in this case not-so-great documentation I concluded that my only option was to use a PowerShell module. I coded up a quick proof of concept using the PowerShell interface available in .NET and while it wasn’t exactly performant, it worked. So I went on to tidy up the code and moved it into a library used by the ASP.NET app and after messing around for a bit with dependency versions the only results I’d get were error messages.
For a while I thought my issue was with the versions of the dependencies I was using, but after doing some testing in my proof of concept app I could rule that out. I got to a point where the same code would work without issue in the POC but without fail return error messages in the real application.
This particular PowerShell module is advertised as using a new fancy REST API, so to troubleshoot I decided to have a look at the requests using Fiddler. It turned out that the requests from the POC where all serialized with PascalCase names while the requests from the application had camelCase names. The REST API would not recognize camelCase named actions and would return error messages stating that the actions were invalid.
How did this happen, then? Well, the PowerShell module is mostly implemented in .NET and uses the Newtonsoft Json library for serializing the requests. I haven’t read the code for the PowerShell module, but I know this since the serialization behavior was affected by the JsonConvert.DefaultSettings from the ASP.NET app. The solution then? Well, if I could have changed the code for the PowerShell module I would have specified a settings object when serializing the requests. But since I couldn’t do that, the solution was to get rid of the global variable - the DefaultSettings, and to instead use local settings objects where appropriate in the ASP.NET app.