web.config
<connectionStrings configBuilders="CS_Environment">
<add name="connectionA" connectionString="EnvVarA" providerName="System.Data.SqlClient"/>
<add name="connectionB" connectionString="EnvVarB" providerName="System.Data.EntityClient"/>
</connectionStrings>
The ConnectionStringSettings
object's ProviderName
will be an empty string instead of "System.Data.SqlClient"
or "System.Data.EntityClient"
.
The Name
and ConnectionString
properties map just fine. If I remove the configBuilders
attribute from the tag, the provider name will be populated. Of course, the correct environment variable no longer will be fetched but the point is the configBuilder is breaking this.
Here is the configuration builder being used for the connection strings:
<add name="CS_Environment" mode="Greedy" prefix="ConnStr_" stripPrefix="true"
type="Microsoft.Configuration.ConfigurationBuilders.EnvironmentConfigBuilder,
Microsoft.Configuration.ConfigurationBuilders.Environment, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
The currently accepted answer of setting providerName order does not seem to have any effect, at least not in v2.0.
In v2.0, the issue is caused by a bug in
ConnectionStringsSectionHandler
which underGreedy
mode completely replaces entire configuration element.Why is this happening?
This is related to how
Greedy
works: it fetches settings from your backing store first and adds every found entry to configuration. Due to the bug, forconnectionStrings
it actually does drop-then-add-new, losing all extra attributes (includingproviderName
) in the process.Workaround: use
Strict
modeWhen using
Strict
mode the configuration values are looked up first and every entry found is updated with override value (if present). Meaning the original conncetionString xml node is kept with all it's attributes, includingprividerName
.Fix: implement custom handler
Start by inheriting from default
ConnectionStringsSectionHandler
and then fix the issue to reuse existing connectionString (or just apply a providerName suitable to your needs).Important step is to register your app to use your handler over the default one.