How to read XML appSettings from external file? - c#

There are a lot of similar questions and I have looked at every one I could find, to no avail.
I'm storing API keys for Google+ authentication in a .config file outside of my solution (in the same level as the solution folder).
I'm attempting to read the values back in Startup.Auth.cs, like so:
public void ConfigureAuth(IAppBuilder app)
{
app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
{
ClientId = WebConfigurationManager.AppSettings.Get("GoogleClientId"),
ClientSecret = WebConfigurationManager.AppSettings.Get("GoogleClientSecret")
});
}
Root Web.config:
<appSettings file="..\Secrets.config"> <!-- Path is correct, relative to Web.config -->
<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>
Secrets.config:
<configuration>
<appSettings>
<add key="GoogleClientId" value="shh" />
<add key="GoogleClientSecret" value="shh" />
</appSettings>
</configuration>

in a .config file outside of my solution (in the same level as the solution folder).
An IIS application is totally unaware of any folders outside of its virtual application folder. There is no "at the same level as a solution file" in the context of a web application because the solution file is not deployed with it.
If you want to put appSettings outside of your application folder, your only built-in choices are the root web.config file, or machine.config file, which are both global to the machine (but specific to the .NET framework version you are running on). See ASP.NET Configuration File Hierarchy and Inheritance.
But just for the record, it is easiest to manage in the long run if you keep application settings in your application's web.config file. Eventually, you will need to change to/add a new web server and you might be scratching your head for a while trying to work out why the settings no longer work when that time comes if they need to be placed outside of your virtual application folder.

Remove the <configuration>...</configuration> tag from Secrets.config
Secrets.config:
<appSettings>
<add key="GoogleClientId" value="shh" />
<add key="GoogleClientSecret" value="shh" />
</appSettings>
Basically you make the appSettingssection the root of the external Secrets.config file.
The same can be done for connection strings using the configSource attribute except that...
Security - Unlike the Secrets.config file, the external connection
strings file must be in the same directory as the root web.config
file, so you'll have to take precautions to ensure you don't check it
into your source repository.
Also try using the ConfigurationManager
app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
{
ClientId = ConfigurationManager.AppSettings["GoogleClientId"],
ClientSecret = ConfigurationManager.AppSettings["GoogleClientSecret"]
});
Referencing articles where I learned about it
Scott Hanselman
Best practices for private config data and connection strings in configuration in ASP.NET and Azure
Official MS documentation
Best practices for deploying passwords and other sensitive data to ASP.NET and Azure App Service

Did you try to verify that the secrets.config is copied after the build?
Verify that by right clicking on the file and viewing the properties that the build action of the file is set to copy always.

Related

How to Override Web.config values with Azure KeyVault in .NET Framework 4.7.1

How can I implement Microsoft's Azure KeyVault in a ASP.NET Framework 4.7.1 WebForms application to override values in web.config with values from KeyVault? I do see references that we need a minimum version of .NET Framework 4.7.1 in order to do it but the examples Microsoft provides are for .NET Core. I have my configs as web.config files instead of appsettings.json. I also have Global.asax.cs files instead of Startup.cs and Program.cs.
To implement Microsoft's Azure KeyVault in a ASP.NET Framework 4.7.1 WebForms application , first you need to create an Azure Key Vault.
You need to provide a resource group, unique name and location ,then
click on Review + Create.
Can refer Steps to create Azure keyvault
here>>(https://learn.microsoft.com/en-us/azure/key-vault/quick-create-portal)
Next select the Secrets blade and add your app settings and
connection strings that can be accessed in web.config file . You can
click on the Generate/Import button and choose the Upload options as
Manual. Then configure your app settings and connection strings -
keys and values to the Name and Value options. And keep other options
as default.
Configuration builders in ASP.NET provide a way to modify and/or override the values coming from your configuration files (Web.config
in the case of ASP.NET) by using different sources (environment
variables, Key Vault, etc.).
Connecting to Azure Key Vault:
To connect to Azure Key Vault from Visual Studio, you need to right
click on the project and select Add > Connected Service menu.
From the options, choose Secure Secrets with Azure Key Vault option.
Now you may need to sign in if not already signed in to your account
and then select rquired key vault from the list.
And click on the Add button to add key vault reference to your
application. This will add reference of the NuGet package
Microsoft.Configuration.ConfigurationBuilders.Azure to the project.
Also it will add some configuration in the Web.Config file.
(OR)
In Solution Explorer, right-click on your project, and select Manage
NuGet Packages. In the Browse tab, locate and install
Microsoft.Configuration.ConfigurationBuilders.Azure
Open your web.config file, and write the following code:
a) Add configSections and configBuilders as below with your keyvault name
<configSections>
<section
name="configBuilders"
type="System.Configuration.ConfigurationBuildersSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
restartOnExternalChanges="false"
requirePermission="false" />
</configSections>
<configBuilders>
<builders>
<add
name="AzureKeyVault"
vaultName="vaultname"
type="Microsoft.Configuration.ConfigurationBuilders.AzureKeyVaultConfigBuilder, Microsoft.Configuration.ConfigurationBuilders.Azure, Version=1.0.0.0, Culture=neutral"
vaultUri="https://vaultname.vault.azure.net" />
</builders>
</configBuilders>
b) Find the appSettings tag, add an attribute configBuilders="AzureKeyVault", and add a line as below:
<appSettings configBuilders="AzureKeyVault">
<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" />
<add key="TextAnalyticsKey" value="from key vault" />
</appSettings>
<connectionStrings configBuilders="AzureKeyVault">
<add name="DefaultConnection" connectionString="from key vault" providerName="System.Data.SqlClient" />
<add key="StorageConnectionString" value="from key vault" />
</connectionStrings>
c) Edit the About method in HomeController.cs, to display the value for confirmation.
public ActionResult About()
{
ViewBag.Message = "Key vault value = " + ConfigurationManager.AppSettings["TextAnalyticsKey"];
}
This way you can connect and use Azure Key Vault in your classic ASP.NET MVC applications,if you’re application running is using .NET Framework 4.7 or later versions.
You can refer following documents for the detailed explaination of the same :
https://learn.microsoft.com/en-us/azure/key-vault/general/vs-key-vault-add-connected-service#added-references-for-aspnet-framework
https://dotnetthoughts.net/azure-key-vault-in-aspnet-mvc/ helps you how to connect and use Azure Key Vault in your ASP.NET MVC application.

Configuring the Seq URL from a single place

I have a solution with a bunch of .net framework applications that are all configured to use Seq for logging. Currently I have the same settings duplicated in every app.config file:
<appSettings>
<add key="serilog:using:Seq" value="Serilog.Sinks.Seq" />
<add key="serilog:write-to:Seq.serverUrl" value="http://localhost:5341" />
</appSettings>
If I would like to be able to configure the Seq URL for all the applications from a single file, not only when running in Visual Studio but also when the system has been deployed.
How can this be done?
I have looked into creating a common settings file and include it in all applications using <appSettings file="CommonSettings.config">, but from what I understand this actually creates a copy of the file for each application.

Set different appSettings key in production server

How can I set a different value when I publish my MVC5 do production server?
Example:
In dev I have
<appSettings>
<add key="XLSFile" value="C:\\temp\\file.xls" />
</appSettings>
And when I publish the project I want to set a different path:
<appSettings>
<add key="XLSFile" value="C:\\projectname\\file.xls" />
</appSettings>
You'll want to use a config file transformation. Essentially you will override the config file for your release build.
For example:
<add key="XLSFile" value="C:\\projectname\\file.xls" xdt:Transform="Replace" xdt:Locator="Match(key)"/>
You can use two config files one with name web.Debug.config and second web.Release.config. First one for development and second for production server when published and now specify different value of key in both files as required

Custom configuration file for different solution projects

I have more than one solution projects for an application with using one app.config for each solution.
Can i do a separate configuration file (other than app.config) for common setting like db name (connection string) ?
Because currently i put these setting in each and every app.config file.
Please try following.
Create one config called "common.config" like below which will be common to all solutions and let's say it's located # "E:/myconfig". Please keep all common setting in this config.
<appSettings>
<add key="connstring" value="conn string value" />
</appSettings>
Now link this common config in you specific solution config lets say web.config using file attribute
<configuration>
<appSettings file="E:\myconfig\Common.config">
<add key="key1" value="value" />
</appSettings>
</configuration>
Hope this will work for you.

Split 'appSettings' section in several web.config files

I'm working on a ASP.NET project and I need to add some settings in appSettings section of my web-app.
Now these settings are growing up, so I'd like to organize them in different files. I've created other web.config files in different directories of my application, adding something like this:
<?xml version="1.0"?>
<configuration>
<system.web>
</system.web>
<appSettings>
<add key="settingKey" value="settingValue" />
</appSettings>
</configuration>
But when I try to access them via ConfigurationManager.AppSettings["settingKey"], I get null.
So, is it possible to split settings in different files? Is there another way to logically organize app settings values?
I know this is too old and probably doesn't even apply to .NET Core but for those coming from Google and using non-.NET Core json config files. Here's what I normally do...
I use configSources to take all config settings out of the web.config. This allows you to a specific config section to a different file by providing a relative location for example here's how you'd declare a configSource in a configuration section (in the root web.config file)...
<configuration>
<log4net configSource="Config\debug\log4net.config" />
<appSettings configSource="config\debug\settings.config" />
<connectionStrings configSource="config\debug\connections.config" />
...
</configuration>
You can name those files whatever you want, just make sure that the path specified and files exist in the solution. Here's what the settings.config file looks like...
<?xml version="1.0"?>
<appSettings>
<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" />
<add key="foo" value="bar" />
</appSettings>
Now, the relative path is relative to the project root...
In picture above you can see that I have provided two different paths for different deployment environments, that's because obviously my conection strings and settings are different in production.
Then you can use configuration transformations so that the application can use the correct config files whether it is in debug or release mode...
This is what the Web.Debug.config file looks like...
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<log4net configSource="Config\debug\log4net.config" xdt:Transform="Replace" />
<appSettings configSource="config\debug\settings.config" xdt:Transform="Replace" />
<connectionStrings configSource="config\debug\connections.config" xdt:Transform="Replace" />
</configuration>
The release one is pretty much the same...replace the paths provided to the configSource attributes.And that's pretty much it.
There are other web.config elements that support configSource settings such as many of the system.serviceModel children element.
You will only be able to see the web.config settings within a directory if the currently executing path is within that directory.
So for example:
/MyDirectory/web.config
is only visible if you are loading a page like:
/Mydirectory/MyTestPage.aspx
You would not see the web.config settings here for example:
/OtherDirectory/MyTestPage.aspx
This post may help:
Creating a custom .config file in asp.net

Categories

Resources