Summary
Enable CA1305 ("Specify IFormatProvider") as a build-enforced analyzer rule, and fix the culture-sensitive formatting it surfaces. CA1305 flags formatting/parsing calls that omit an explicit culture and therefore fall back to CultureInfo.CurrentCulture, so the produced string varies with the machine/thread locale.
This rule is disabled by default in the SDK's current analysis mode (AnalysisMode=Default), so it never fires today even though EnableNETAnalyzers=true and TreatWarningsAsErrors=true are set in eng/build/Engineering.props.
Why this matters (real correctness risk, not style)
The SDK turns typed parameters into wire text — JSON bodies and URL paths/query strings — which must be culture-invariant to match connector backends. Under a non-invariant CurrentCulture the current code can emit wrong bytes:
- Floating-point params in
de-DE serialize with a comma decimal separator (3,14) → malformed URL/query.
- Integers under digit-substituting locales (
ar-SA, fa-IR) render non-ASCII digits → malformed query.
DateTime values render culture-formatted / with non-ASCII digits → invalid ISO-8601 on the wire.
This is silent on invariant-culture CI (and Azure Functions defaults often use invariant globalization), and only fails in specific customer locales — the worst failure mode.
Evidence (from a local AnalysisMode=All build)
CA1305 fires ~1,400 times. Two representative surfaces:
1. Hand-written — Iso8601DateTimeConverter (src/Azure.Connectors.Sdk/Serialization/JsonConverters.cs):
// Write (line ~35): renders digits with CurrentCulture
writer.WriteStringValue(value.ToUniversalTime().ToString(DateTimeFormat));
// Read: also CurrentCulture
return DateTime.Parse(value, null, System.Globalization.DateTimeStyles.RoundtripKind);
Both should pass CultureInfo.InvariantCulture.
2. Generated clients — parameter → URL construction (bulk of the hits), e.g. AzureADExtensions / AzureAutomationExtensions:
queryParams.Add($"$top={Uri.EscapeDataString(top.Value.ToString())}"); // int.ToString(), no culture
var path = $".../resourcegroups/{Uri.EscapeDataString(subscription.ToString())}"; // no culture
Guid/string params are harmless, but numeric and DateTime params are not.
Scope / considerations
- Generated code is in scope. The generated clients are produced by our own CodefulSdkGenerator (BPM repo) and are core to the value proposition; culture-broken parameter formatting is a real product bug. The generated hits must be fixed in the generator's emit templates (make every
param.ToString() in path/query building culture-invariant, or route through an invariant formatting helper) — one generator change fixes all ~1,400 and every future connector — not per-file suppressions.
- Severity: start as
warning (which TreatWarningsAsErrors escalates to error) via .editorconfig (dotnet_diagnostic.CA1305.severity = warning), rather than raising the whole AnalysisMode, to keep the change targeted.
Tasks
Acceptance criteria
Filed from analysis on PR #196; not part of that PR's scope. Companion to #199 (CA1062).
Summary
Enable CA1305 ("Specify
IFormatProvider") as a build-enforced analyzer rule, and fix the culture-sensitive formatting it surfaces. CA1305 flags formatting/parsing calls that omit an explicit culture and therefore fall back toCultureInfo.CurrentCulture, so the produced string varies with the machine/thread locale.This rule is disabled by default in the SDK's current analysis mode (
AnalysisMode=Default), so it never fires today even thoughEnableNETAnalyzers=trueandTreatWarningsAsErrors=trueare set ineng/build/Engineering.props.Why this matters (real correctness risk, not style)
The SDK turns typed parameters into wire text — JSON bodies and URL paths/query strings — which must be culture-invariant to match connector backends. Under a non-invariant
CurrentCulturethe current code can emit wrong bytes:de-DEserialize with a comma decimal separator (3,14) → malformed URL/query.ar-SA,fa-IR) render non-ASCII digits → malformed query.DateTimevalues render culture-formatted / with non-ASCII digits → invalid ISO-8601 on the wire.This is silent on invariant-culture CI (and Azure Functions defaults often use invariant globalization), and only fails in specific customer locales — the worst failure mode.
Evidence (from a local
AnalysisMode=Allbuild)CA1305 fires ~1,400 times. Two representative surfaces:
1. Hand-written —
Iso8601DateTimeConverter(src/Azure.Connectors.Sdk/Serialization/JsonConverters.cs):Both should pass
CultureInfo.InvariantCulture.2. Generated clients — parameter → URL construction (bulk of the hits), e.g.
AzureADExtensions/AzureAutomationExtensions:Guid/stringparams are harmless, but numeric andDateTimeparams are not.Scope / considerations
param.ToString()in path/query building culture-invariant, or route through an invariant formatting helper) — one generator change fixes all ~1,400 and every future connector — not per-file suppressions.warning(whichTreatWarningsAsErrorsescalates to error) via.editorconfig(dotnet_diagnostic.CA1305.severity = warning), rather than raising the wholeAnalysisMode, to keep the change targeted.Tasks
Iso8601DateTimeConverterWriteandReadto useCultureInfo.InvariantCulture(Connectors-NET-SDK repo).dotnet_diagnostic.CA1305.severityin.editorconfigonce the surfaced violations are resolved.Acceptance criteria
.editorconfig).Iso8601DateTimeConverterround-trips correctly under a non-invariant culture (e.g.ar-SA/de-DE).Filed from analysis on PR #196; not part of that PR's scope. Companion to #199 (CA1062).