0

I'm trying to split up private information out of config files. I've found that the project type can't be a website. But it still doesn't work for appsettings at all, for connection strings, it uses the Debug build version, even when on Release mode.

My project is a default Visual Studio Single Page Web Application with authentication removed. The following secrets files:

**Web.settings.secrets:**
<?xml version="1.0" encoding="utf-8"?>
<connectionStrings xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
    <add name="Default" providerName="Oracle.ManagedDataAccess.Client" connectionString="Release connectionString" xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>

**Web.settings.Release.secrets:**
<?xml version="1.0" encoding="utf-8" ?>
<appSettings xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
    <add name="setting" value="Release setting" xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</appSettings>

**Web.connection.secrets:**
<?xml version="1.0" encoding="utf-8"?>
<connectionStrings>
    <add name="Default" providerName="Oracle.ManagedDataAccess.Client" connectionString="Debug connectionString" />
    <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-WebApp-20170304072749.mdf;Initial Catalog=aspnet-WebApp-20170304072749;Integrated Security=True"
      providerName="System.Data.SqlClient" />
</connectionStrings>

**Web.connection.Release.secrets:**
<?xml version="1.0" encoding="utf-8"?>
<connectionStrings xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
    <add name="Default" providerName="Oracle.ManagedDataAccess.Client" connectionString="Release connectionString" xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>

The Web.config and Web.Release.config refer to these files in their connectionStrings and appSettings elements.
Web.config:

<?xml version="1.0" encoding="utf-8"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=301879
  -->
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
    <connectionStrings configSource="Web.connection.secrets">
  </connectionStrings>
  <appSettings file="Web.settings.secrets">
    <add key="webpages:Version" value="3.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
  </appSettings>
  <system.web>
    <authentication mode="None" />
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
  </system.web>
  <system.webServer>
    <modules>
      <remove name="FormsAuthentication" />
    </modules>
  <handlers>
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="OPTIONSVerbHandler" />
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers></system.webServer>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Owin.Security.OAuth" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Owin.Security.Cookies" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" />
        <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="mssqllocaldb" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
</configuration>

Web.Release.config:

<!-- For more information on using Web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=301874 -->

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <!--
    In the example below, the "SetAttributes" transform will change the value of
    "connectionString" to use "ReleaseSQLServer" only when the "Match" locator
    finds an attribute "name" that has a value of "MyDB".

  -->
    <connectionStrings configSource="Web.connection.Release.secrets">
    </connectionStrings>
<appSettings file="Web.settings.Release.secrets">
</appSettings>
  <system.web>
    <compilation xdt:Transform="RemoveAttributes(debug)" />
    <!--
      In the example below, the "Replace" transform will replace the entire
      <customErrors> section of your Web.config file.
      Note that because there is only one customErrors section under the
      <system.web> node, there is no need to use the "xdt:Locator" attribute.

      <customErrors defaultRedirect="GenericError.htm"
        mode="RemoteOnly" xdt:Transform="Replace">
        <error statusCode="500" redirect="InternalError.htm"/>
      </customErrors>
    -->
  </system.web>
</configuration>

I would really like to:

  1. Include connection strings from the right secrets file, based on the used build configuration.
  2. Include app settings from the Web.setting.secrets file at default.
  3. Include app settings from right secrets file, based on the used build configuration.
Community
  • 1
  • 1
MrFox
  • 4,852
  • 7
  • 45
  • 81

1 Answers1

1

Your first block - what you are referring to as the separate settings files shouldn't have XML declarations, nor transforms. Examples:

  • Secrets.config file

    <add name="setting" value="Release setting" />
    <add name="foo" value="bar" />
    

Your last block, which you are referring to as your release config should have transforms:

<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
...

    <connectionStrings 
        configSource="Web.connection.Release.secrets.config" 
        xdt:Transform="Replace">
    </connectionStrings>

   <!-- AppSettings file location sample - leaves child elements intact-->
   <appSettings file="releasekeys.config" xdt:Transform="SetAttributes(file)"></appSettings>

REF: Web.config Transformation Syntax for Web Application Project Deployment

Hth ~

EdSF
  • 11,753
  • 6
  • 42
  • 83
  • Surprisingly, that has no effect :( You'd think it stays in cache or something like that. But I've tried a different browser, used Chrome's empty cache and hard reload and done a Clean => Rebuild. The site is not hosted in IIS, just the vs IISExpress, where all running sites have been stopped. Since the elements are added `` I also tried to include their surrounding element. So just removing the XML declaration. – MrFox Mar 05 '17 at 07:01
  • Hmm..wouldn't have anything to do with it. When you `Publish` your site, it will transform your `web.config`. Caching has nothing to do with it - each time you modify/change `web.config`, your application will restart with your application's new settings (has nothing to do with browser caching). The only "caching" that can come into play is your host's file system (there could be a difference between _overwriting_ a file and _deleting files first and then replacing them_. You can publish your site to a local folder and inspect the web.config to verify. – EdSF Mar 05 '17 at 07:32
  • Also you're not `adding` (based on your web.config above). You're (should be) doing a `replace`. I'm assuming your `debug` settings are `web.connections.secrets.config` and you want to replace them with `web.connections.release.secrets.config`. Also note the `.config` (file naming) – EdSF Mar 05 '17 at 07:37
  • I'm not really publishing the site, but debugging it with Chrome. Maybe putting the files in binary does the same, but the config file in there, just has the same content, no replaces or includes, the original references to the .secrets files are still there. The .secrets files have been copied into the bin folder. – MrFox Mar 05 '17 at 11:39
  • I'm doing replaces in the files specific for a build configuration but not the basic ones. – MrFox Mar 05 '17 at 11:40
  • `Release` transforms are applied [when you _deploy_ (aka "Publish")](https://msdn.microsoft.com/en-us/library/dd465318(v=vs.100).aspx). That's why I mentioned that you try to `Publish` locally (some folder in your system) so you can see/inspect the result of the transforms you are setting...Hth.. – EdSF Mar 05 '17 at 16:08
  • I tried watching a preview of the transform, it looked good for the connectionstring. But for the app settings part it can't replace the reference to the different secrets file while keeping the original app settings. The file attribute on the appSettings should allow merging, altough currently it doesn't work at all. – MrFox Mar 05 '17 at 21:13
  • Not true. Works fine. e.g. `` Here's [reference to syntax](https://msdn.microsoft.com/en-us/library/dd465326(v=vs.100).aspx). – EdSF Mar 05 '17 at 21:34
  • I was using name in appSettings elements, where I need to use key. So it's a key-value pair. It's working now. Please edit your answer to fix my mistake on this. – MrFox Mar 06 '17 at 07:39