Fixed: "error CA1305: The behavior of 'int.Parse(string)' could vary based on the current user's locale settings"
int.Parse on a number from configuration stopped the build with error CA1305: The behavior of 'int.Parse(string)' could vary based on the current user's locale settings. The analyzer has a point, and the fix is one argument, once you decide whose culture the text is in.
What I Was Doing
My .NET C# solution builds with AnalysisLevel set to latest-recommended and warnings as errors. I was reading two numbers from configuration:
mySql.CommandTimeout(int.Parse(configuration["Database:CommandTimeoutSeconds"] ?? "0"));
dotnet build
What I Expected
Build succeeded.
What I Got
Build FAILED.
src/Dewiride.Inventory.Data/InventoryDataServiceCollectionExtensions.cs(62,125): error CA1305: The behavior of 'int.Parse(string)' could vary based on the current user's locale settings. Replace this call in 'IServiceCollection.AddInventoryData(IConfiguration)' with a call to 'int.Parse(string, IFormatProvider)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)
src/Dewiride.Inventory.Data/InventoryDataServiceCollectionExtensions.cs(65,38): error CA1305: The behavior of 'int.Parse(string)' could vary based on the current user's locale settings. Replace this call in 'IServiceCollection.AddInventoryData(IConfiguration)' with a call to 'int.Parse(string, IFormatProvider)'. (https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1305)

What I Checked
Why it's an error. CA1305 is a warning, and TreatWarningsAsErrors makes it stop the build.
The rule. CA1305 fires when "A call is made to a method that has an overload that accepts a System.IFormatProvider argument, and that overload isn't called." Its guidance covers my case: "If the value will be stored and accessed by software (persisted to a file or database), use the invariant culture."
Why It Happens
int.Parse(string) uses the current culture of whichever machine runs the code. For whole numbers that's rarely a problem, but in general, a number's text can mean different things in different cultures, and that would make the app's behaviour depend on where it runs. The rule asks you to say which culture you meant.
The Fix
Configuration is written for software, so it has one fixed format. Pass the invariant culture:
mySql.CommandTimeout(int.Parse(configuration["Database:CommandTimeoutSeconds"] ?? "0", CultureInfo.InvariantCulture));
With this at the top of the file:
using System.Globalization;
If the text comes from a person typing into your app, use CultureInfo.CurrentCulture instead, as the rule's guidance says.
After the Fix
Build succeeded.
0 Warning(s)
0 Error(s)

Common Mistakes
| Mistake | What happens | Do this instead |
|---|---|---|
| Suppressing the rule | Real culture bugs go unnoticed | Pass the culture |
| Turning off warnings as errors | Every other warning slips through too | Fix this one |
| Using the invariant culture for what people type | Someone's decimal comma breaks | Use their culture for their input |
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
The same error on ToString() | The rule covers formatting too | Pass the culture there as well |
| You don't see it on another project | A lower analysis level | Check AnalysisLevel |
Conclusion
CA1305 asks you to say which culture a number's text is in. For configuration and other text meant for software, it's CultureInfo.InvariantCulture.
Additional Resources
- CA1305: Specify IFormatProvider — the rule.
