No providerName Found When Using Configuration Builder

487 Views Asked by At

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" />
1

There are 1 best solutions below

1
On BEST ANSWER

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 under Greedy 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, for connectionStrings it actually does drop-then-add-new, losing all extra attributes (including providerName) in the process.

Workaround: use Strict mode

When 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, including prividerName.

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.