AspNetCore.Docs/aspnetcore/fundamentals/configuration.md

358 lines
17 KiB
Markdown
Raw Normal View History

2016-10-29 01:35:15 +08:00
---
title: Configuration in ASP.NET Core
2016-12-08 12:08:45 +08:00
author: rick-anderson
description: Demonstrates the configuration API
keywords: ASP.NET Core, configuration, JSON
2016-10-29 01:35:15 +08:00
ms.author: riande
manager: wpickett
ms.date: 6/24/2017
2016-10-29 01:35:15 +08:00
ms.topic: article
ms.assetid: b3a5984d-e172-42eb-8a48-547e4acb6806
2016-11-17 08:24:57 +08:00
ms.technology: aspnet
ms.prod: asp.net-core
2016-10-29 01:35:15 +08:00
uid: fundamentals/configuration
---
<a name=fundamentals-configuration></a>
# Configuration in ASP.NET Core
2016-12-08 12:08:45 +08:00
[Rick Anderson](https://twitter.com/RickAndMSFT), [Mark Michaelis](http://intellitect.com/author/mark-michaelis/), [Steve Smith](http://ardalis.com), [Daniel Roth](https://github.com/danroth27)
The configuration API provides a way of configuring an app based on a list of name-value pairs. Configuration is read at runtime from multiple sources. The name-value pairs can be grouped into a multi-level hierarchy. There are configuration providers for:
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
* File formats (INI, JSON, and XML)
* Command-line arguments
* Environment variables
* In-memory .NET objects
* An encrypted user store
Key Vault Configuration Provider doc (#2531) * Update configuration.md * Create key-vault-configuration.md * Create appsettings.json * Add files via upload * Update README.md * Update KeyVaultConfigProviderSample.csproj * Create sample-output.png * Add files via upload * Update key-vault-configuration.md * Update Startup.cs * Add files via upload * Add files via upload * Add files via upload * Update Startup.cs * Update appsettings.json * Update Startup.cs * Update key-vault-configuration.md * Update key-vault-configuration.md * Update key-vault-configuration.md * Update key-vault-configuration.md * Update key-vault-configuration.md * Add files via upload * Add files via upload * Add files via upload * Update key-vault-configuration.md * Update key-vault-configuration.md * Update key-vault-configuration.md * Update key-vault-configuration.md * Update key-vault-configuration.md * Update key-vault-configuration.md * Update key-vault-configuration.md * Update key-vault-configuration.md * Update key-vault-configuration.md * Update configuration.md * Update key-vault-configuration.md * Update key-vault-configuration.md * Update key-vault-configuration.md * Update appsettings.json * React to feedback * React to feedback * Update index.md * Update toc.md * Update configuration.md * React to feedback - "When to use" section * Add a phrase to KeyVaultClient bit * Update key-vault-configuration.md * React to feedback * Minor update to ms.date * New implementation and local secret storage * Update KeyVaultConfigProviderSample.csproj * Update Program.cs * Minor phrasing adjustments * Update KeyVaultConfigProviderSample.csproj * Minor phrasing update * Add files via upload * Remove en-us from links * Update web.config * Delete License.txt * Update Markup.cs * Update Program.cs * Update Startup.cs * Update ms.date * Note .NET Core target 1.1.0+ * Update KeyVaultConfigProviderSample.csproj * Update KeyVaultConfigProviderSample.csproj * Remove compiler\resources line It isn't necessary, and it isn't in the templates. * Update KeyVaultConfigProviderSample.csproj * Create launchSettings.json * Update KeyVaultConfigProviderSample.csproj * Update Startup.cs * Update KeyVaultConfigProviderSample.csproj * Update KeyVaultConfigProviderSample.csproj * Update key-vault-configuration.md * Update key-vault-configuration.md * Update key-vault-configuration.md * Update key-vault-configuration.md * Update key-vault-configuration.md * Minor updates * Minor update * Update the doc ms.date * Minor update
2017-02-14 04:03:08 +08:00
* [Azure Key Vault](xref:security/key-vault-configuration)
2016-12-08 12:08:45 +08:00
* Custom providers, which you install or create
Each configuration value maps to a string key. Theres built-in binding support to deserialize settings into a custom [POCO](https://en.wikipedia.org/wiki/Plain_Old_CLR_Object) object (a simple .NET class with properties).
2016-10-29 01:35:15 +08:00
[View or download sample code](https://github.com/aspnet/docs/tree/master/aspnetcore/fundamentals/configuration/sample)
2016-10-29 01:35:15 +08:00
## Simple configuration
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
The following console app uses the JSON configuration provider:
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
[!code-csharp[Main](configuration/sample/src/ConfigJson/Program.cs)]
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
The app reads and displays the following configuration settings:
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
[!code-json[Main](configuration/sample/src/ConfigJson/appsettings.json)]
2016-10-29 01:35:15 +08:00
Configuration consists of a hierarchical list of name-value pairs in which the nodes are separated by a colon. To retrieve a value, access the `Configuration` indexer with the corresponding items key:
2016-10-29 01:35:15 +08:00
```csharp
Console.WriteLine($"option1 = {Configuration["subsection:suboption1"]}");
2016-12-08 12:08:45 +08:00
```
2016-10-29 01:35:15 +08:00
To work with arrays in JSON-formatted configuration sources, use a array index as part of the colon-separated string. The following example gets the name of the first item in the preceding `wizards` array:
```csharp
Console.Write($"{Configuration["wizards:0:Name"]}, ");
```
Name-value pairs written to the built in `Configuration` providers are **not** persisted, however, you can create a custom provider that saves values. See [custom configuration provider](xref:fundamentals/configuration#custom-config-providers).
2016-10-29 01:35:15 +08:00
The preceding sample uses the configuration indexer to read values. To access configuration outside of `Startup`, use the [options pattern](xref:fundamentals/configuration#options-config-objects). The *options pattern* is shown later in this article.
2016-10-29 01:35:15 +08:00
It's typical to have different configuration settings for different environments, for example, development, test and production. The following highlighted code adds two configuration providers to three sources:
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
1. JSON provider, reading *appsettings.json*
2. JSON provider, reading *appsettings.\<EnvironmentName>.json*
3. Environment variables provider
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
[!code-csharp[Main](configuration/sample/src/WebConfigBind/Startup.cs?name=snippet2&highlight=7-9)]
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
See [AddJsonFile](https://docs.microsoft.com/aspnet/core/api/microsoft.extensions.configuration.jsonconfigurationextensions) for an explanation of the parameters. `reloadOnChange` is only supported in ASP.NET Core 1.1 and higher.
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
Configuration sources are read in the order they are specified. In the code above, the environment variables are read last. Any configuration values set through the environment would replace those set in the two previous providers.
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
The environment is typically set to one of `Development`, `Staging`, or `Production`. See [Working with Multiple Environments](environments.md) for more information.
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
Configuration considerations:
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
* `IOptionsSnapshot` can reload configuration data when it changes. Use `IOptionsSnapshot` if you need to reload configuration data. See [IOptionsSnapshot](#ioptionssnapshot) for more information.
* Configuration keys are case insensitive.
* A best practice is to specify environment variables last, so that the local environment can override anything set in deployed configuration files.
* **Never** store passwords or other sensitive data in configuration provider code or in plain text configuration files. Don't use production secrets in your development or test environments. Instead, specify secrets outside the project tree, so they cannot be accidentally committed into your repository. Learn more about [Working with Multiple Environments](environments.md) and managing [safe storage of app secrets during development](../security/app-secrets.md).
2016-12-08 12:08:45 +08:00
* If `:` cannot be used in environment variables in your system, replace `:` with `__` (double underscore).
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
<a name=options-config-objects></a>
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
## Using Options and configuration objects
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
The options pattern uses custom options classes to represent a group of related settings. We recommended that you create decoupled classes for each feature within your app. Decoupled classes follow:
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
* The [Interface Segregation Principle (ISP)](http://deviq.com/interface-segregation-principle/) : Classes depend only on the configuration settings they use.
* [Separation of Concerns](http://deviq.com/separation-of-concerns/) : Settings for different parts of your app are not dependent or coupled with one another.
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
The options class must be non-abstract with a public parameterless constructor. For example:
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
[!code-csharp[Main](configuration/sample/src/UsingOptions/Models/MyOptions.cs)]
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
<a name=options-example></a>
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
In the following code, the JSON configuration provider is enabled. The `MyOptions` class is added to the service container and bound to configuration.
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
[!code-csharp[Main](configuration/sample/src/UsingOptions/Startup.cs?name=snippet1&highlight=8,20-22)]
2016-10-29 01:35:15 +08:00
The following [controller](../mvc/controllers/index.md) uses [constructor Dependency Injection](xref:fundamentals/dependency-injection#what-is-dependency-injection) on [`IOptions<TOptions>`](https://docs.microsoft.com/en-us/aspnet/core/api/microsoft.extensions.options.ioptions-1) to access settings:
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
[!code-csharp[Main](configuration/sample/src/UsingOptions/Controllers/HomeController.cs?name=snippet1)]
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
With the following *appsettings.json* file:
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
[!code-json[Main](configuration/sample/src/UsingOptions/appsettings1.json)]
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
The `HomeController.Index` method returns `option1 = value1_from_json, option2 = 2`.
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
Typical apps won't bind the entire configuration to a single options file. Later on I'll show how to use `GetSection` to bind to a section.
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
In the following code, a second `IConfigureOptions<TOptions>` service is added to the service container. It uses a delegate to configure the binding with `MyOptions`.
2016-10-29 01:35:15 +08:00
[!code-csharp[Main](configuration/sample/src/UsingOptions/Startup2.cs?name=snippet1&highlight=9-13)]
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
You can add multiple configuration providers. Configuration providers are available in NuGet packages. They are applied in order they are registered.
2016-10-29 01:35:15 +08:00
Each call to `Configure<TOptions>` adds an `IConfigureOptions<TOptions>` service to the service container. In the preceding example, the values of `Option1` and `Option2` are both specified in *appsettings.json* -- but the value of `Option1` is overridden by the configured delegate.
2016-10-29 01:35:15 +08:00
When more than one configuration service is enabled, the last configuration source specified "wins" (sets the configuration value). In the preceding code, the `HomeController.Index` method returns `option1 = value1_from_action, option2 = 2`.
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
When you bind options to configuration, each property in your options type is bound to a configuration key of the form `property[:sub-property:]`. For example, the `MyOptions.Option1` property is bound to the key `Option1`, which is read from the `option1` property in *appsettings.json*. A sub-property sample is shown later in this article.
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
In the following code, a third `IConfigureOptions<TOptions>` service is added to the service container. It binds `MySubOptions` to the section `subsection` of the *appsettings.json* file:
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
[!code-csharp[Main](configuration/sample/src/UsingOptions/Startup3.cs?name=snippet1&highlight=16-17)]
Note: This extension method requires the `Microsoft.Extensions.Options.ConfigurationExtensions` NuGet package.
2016-12-08 12:08:45 +08:00
Using the following *appsettings.json* file:
[!code-json[Main](configuration/sample/src/UsingOptions/appsettings.json)]
The `MySubOptions` class:
[!code-csharp[Main](configuration/sample/src/UsingOptions/Models/MySubOptions.cs)]
With the following `Controller`:
[!code-csharp[Main](configuration/sample/src/UsingOptions/Controllers/HomeController2.cs?name=snippet1)]
`subOption1 = subvalue1_from_json, subOption2 = 200` is returned.
<a name=in-memory-provider></a>
## IOptionsSnapshot
*Requires ASP.NET Core 1.1 or higher.*
`IOptionsSnapshot` supports reloading configuration data when the configuration file has changed. It has minimal overhead. Using `IOptionsSnapshot` with `reloadOnChange: true`, the options are bound to `IConfiguration` and reloaded when changed.
2016-12-08 12:08:45 +08:00
The following sample demonstrates how a new `IOptionsSnapshot` is created after *config.json* changes. Requests to the server will return the same time when *config.json* has **not** changed. The first request after *config.json* changes will show a new time.
2016-12-08 12:08:45 +08:00
[!code-csharp[Main](configuration/sample/IOptionsSnapshot2/Startup.cs?name=snippet1&highlight=1-9,13-18,32,33,52,53)]
The following image shows the server output:
![browser image showing "Last Updated: 11/22/2016 4:43 PM"](configuration/_static/first.png)
Refreshing the browser doesn't change the message value or time displayed (when *config.json* has not changed).
Change and save the *config.json* and then refresh the browser:
![browser image showing "Last Updated to,e: 11/22/2016 4:53 PM"](configuration/_static/change.png)
## In-memory provider and binding to a POCO class
The following sample shows how to use the in-memory provider and bind to a class:
[!code-csharp[Main](configuration/sample/src/InMemory/Program.cs)]
Configuration values are returned as strings, but binding enables the construction of objects. Binding allows you to retrieve POCO objects or even entire object graphs. The following sample shows how to bind to `MyWindow` and use the options pattern with a ASP.NET Core MVC app:
2016-12-08 12:08:45 +08:00
[!code-csharp[Main](configuration/sample/src/WebConfigBind/MyWindow.cs)]
[!code-json[Main](configuration/sample/src/WebConfigBind/appsettings.json)]
Bind the custom class in `ConfigureServices` in the `Startup` class:
[!code-csharp[Main](configuration/sample/src/WebConfigBind/Startup.cs?name=snippet1&highlight=3,4)]
Display the settings from the `HomeController`:
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
[!code-csharp[Main](configuration/sample/src/WebConfigBind/Controllers/HomeController.cs)]
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
### GetValue
2016-10-29 01:35:15 +08:00
The following sample demonstrates the [GetValue<T>](https://docs.microsoft.com/aspnet/core/api/microsoft.extensions.configuration.configurationbinder#Microsoft_Extensions_Configuration_ConfigurationBinder_GetValue_Microsoft_Extensions_Configuration_IConfiguration_System_Type_System_String_System_Object_) extension method:
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
[!code-csharp[Main](configuration/sample/src/InMemoryGetValue/Program.cs?highlight=25-27)]
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
The ConfigurationBinders `GetValue<T>` method allows you to specify a default value (80 in the sample). `GetValue<T>` is for simple scenarios and does not bind to entire sections. `GetValue<T>` gets scalar values from `GetSection(key).Value` converted to a specific type.
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
## Binding to an object graph
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
You can recursively bind to each object in a class. Consider the following `AppOptions` class:
[!code-csharp[Main](configuration/sample/src/ObjectGraph/AppOptions.cs)]
The following sample binds to the `AppOptions` class:
[!code-csharp[Main](configuration/sample/src/ObjectGraph/Program.cs?highlight=19-20)]
2016-12-08 12:08:45 +08:00
**ASP.NET Core 1.1** and higher can use `Get<T>`, which works with entire sections. `Get<T>` can be more convienent than using `Bind`. The following code shows how to use `Get<T>` with the sample above:
```csharp
var appConfig = config.GetSection("App").Get<AppOptions>();
2016-12-08 12:08:45 +08:00
```
Using the following *appsettings.json* file:
[!code-json[Main](configuration/sample/src/ObjectGraph/appsettings.json)]
The program displays `Height 11`.
The following code can be used to unit test the configuration:
```csharp
[Fact]
public void CanBindObjectTree()
{
var dict = new Dictionary<string, string>
{
{"App:Profile:Machine", "Rick"},
{"App:Connection:Value", "connectionstring"},
{"App:Window:Height", "11"},
{"App:Window:Width", "11"}
};
var builder = new ConfigurationBuilder();
builder.AddInMemoryCollection(dict);
var config = builder.Build();
var options = new AppOptions();
config.GetSection("App").Bind(options);
Assert.Equal("Rick", options.Profile.Machine);
Assert.Equal(11, options.Window.Height);
Assert.Equal(11, options.Window.Width);
Assert.Equal("connectionstring", options.Connection.Value);
}
```
2016-10-29 01:35:15 +08:00
<a name=custom-config-providers></a>
## Basic sample of Entity Framework custom provider
2016-12-08 12:08:45 +08:00
In this section, a basic configuration provider that reads name-value pairs from a database using EF is created.
2016-12-08 12:08:45 +08:00
Define a `ConfigurationValue` entity for storing configuration values in the database:
[!code-csharp[Main](configuration/sample/src/CustomConfigurationProvider/ConfigurationValue.cs)]
Add a `ConfigurationContext` to store and access the configured values:
<!-- literal_block {"xml:space": "preserve", "language": "c#", "dupnames": [], "linenos": false, "classes": [], "ids": [], "backrefs": [], "source": "/Users/shirhatti/src/Docs/aspnet/fundamentals/configuration/sample/src/CustomConfigurationProvider/ConfigurationContext.cs", "highlight_args": {"linenostart": 1, "hl_lines": [7]}, "names": []} -->
[!code-csharp[Main](configuration/sample/src/CustomConfigurationProvider/ConfigurationContext.cs?name=snippet1)]
Create an class that implements [IConfigurationSource](https://docs.microsoft.com/en-us/aspnet/core/api/microsoft.extensions.configuration.iconfigurationsource):
2016-12-08 12:08:45 +08:00
[!code-csharp[Main](configuration/sample/src/CustomConfigurationProvider/EntityFrameworkConfigurationSource.cs?highlight=7)]
Create the custom configuration provider by inheriting from [ConfigurationProvider](https://docs.microsoft.com/en-us/aspnet/core/api/microsoft.extensions.configuration.configurationprovider). The configuration provider initializes the database when it's empty:
[!code-csharp[Main](configuration/sample/src/CustomConfigurationProvider/EntityFrameworkConfigurationProvider.cs?highlight=9,18-31,38-39)]
2016-12-08 12:08:45 +08:00
The highlighted values from the database ("value_from_ef_1" and "value_from_ef_2") are displayed when the sample is run.
You can add an `EFConfigSource` extension method for adding the configuration source:
[!code-csharp[Main](configuration/sample/src/CustomConfigurationProvider/EntityFrameworkExtensions.cs?highlight=12)]
The following code shows how to use the custom `EFConfigProvider`:
[!code-csharp[Main](configuration/sample/src/CustomConfigurationProvider/Program.cs?highlight=20-25)]
2016-12-08 12:08:45 +08:00
Note the sample adds the custom `EFConfigProvider` after the JSON provider, so any settings from the database will override settings from the *appsettings.json* file.
Using the following *appsettings.json* file:
[!code-json[Main](configuration/sample/src/CustomConfigurationProvider/appsettings.json)]
The following is displayed:
```
key1=value_from_ef_1
key2=value_from_ef_2
key3=value_from_json_3
```
2016-12-08 12:08:45 +08:00
## CommandLine configuration provider
The following sample enables the CommandLine configuration provider last:
[!code-csharp[Main](configuration/sample/src/CommandLine/Program.cs)]
Use the following to pass in configuration settings:
```
dotnet run /Profile:MachineName=Bob /App:MainWindow:Left=1234
```
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
Which displays:
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
```
Hello Bob
Left 1234
```
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
The `GetSwitchMappings` method allows you to use `-` rather than `/` and it strips the leading subkey prefixes. For example:
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
```
dotnet run -MachineName=Bob -Left=7734
```
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
Displays:
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
```
Hello Bob
Left 7734
```
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
Command-line arguments must include a value (it can be null). For example:
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
```
dotnet run /Profile:MachineName=
```
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
Is OK, but
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
```
dotnet run /Profile:MachineName
```
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
results in an exception. An exception will be thrown if you specify a command-line switch prefix of - or -- for which theres no corresponding switch mapping.
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
## The *web.config* file
2016-10-29 01:35:15 +08:00
A *web.config* file is required when you host the app in IIS or IIS-Express. *web.config* turns on the AspNetCoreModule in IIS to launch your app. Settings in *web.config* enable the AspNetCoreModule in IIS to launch your app and configure other IIS settings and modules. If you are using Visual Studio and delete *web.config*, Visual Studio will create a new one.
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
### Additional notes
2016-10-29 01:35:15 +08:00
* Dependency Injection (DI) is not set up until after `ConfigureServices` is invoked.
* The configuration system is not DI aware.
2016-12-08 12:08:45 +08:00
* `IConfiguration` has two specializations:
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
* `IConfigurationRoot` Used for the root node. Can trigger a reload.
* `IConfigurationSection` Represents a section of configuration values. The `GetSection` and `GetChildren` methods return an `IConfigurationSection`.
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
### Additional Resources
2016-10-29 01:35:15 +08:00
2016-12-08 12:08:45 +08:00
* [Working with Multiple Environments](environments.md)
* [Safe storage of app secrets during development](../security/app-secrets.md)
* [Dependency Injection](dependency-injection.md)
Key Vault Configuration Provider doc (#2531) * Update configuration.md * Create key-vault-configuration.md * Create appsettings.json * Add files via upload * Update README.md * Update KeyVaultConfigProviderSample.csproj * Create sample-output.png * Add files via upload * Update key-vault-configuration.md * Update Startup.cs * Add files via upload * Add files via upload * Add files via upload * Update Startup.cs * Update appsettings.json * Update Startup.cs * Update key-vault-configuration.md * Update key-vault-configuration.md * Update key-vault-configuration.md * Update key-vault-configuration.md * Update key-vault-configuration.md * Add files via upload * Add files via upload * Add files via upload * Update key-vault-configuration.md * Update key-vault-configuration.md * Update key-vault-configuration.md * Update key-vault-configuration.md * Update key-vault-configuration.md * Update key-vault-configuration.md * Update key-vault-configuration.md * Update key-vault-configuration.md * Update key-vault-configuration.md * Update configuration.md * Update key-vault-configuration.md * Update key-vault-configuration.md * Update key-vault-configuration.md * Update appsettings.json * React to feedback * React to feedback * Update index.md * Update toc.md * Update configuration.md * React to feedback - "When to use" section * Add a phrase to KeyVaultClient bit * Update key-vault-configuration.md * React to feedback * Minor update to ms.date * New implementation and local secret storage * Update KeyVaultConfigProviderSample.csproj * Update Program.cs * Minor phrasing adjustments * Update KeyVaultConfigProviderSample.csproj * Minor phrasing update * Add files via upload * Remove en-us from links * Update web.config * Delete License.txt * Update Markup.cs * Update Program.cs * Update Startup.cs * Update ms.date * Note .NET Core target 1.1.0+ * Update KeyVaultConfigProviderSample.csproj * Update KeyVaultConfigProviderSample.csproj * Remove compiler\resources line It isn't necessary, and it isn't in the templates. * Update KeyVaultConfigProviderSample.csproj * Create launchSettings.json * Update KeyVaultConfigProviderSample.csproj * Update Startup.cs * Update KeyVaultConfigProviderSample.csproj * Update KeyVaultConfigProviderSample.csproj * Update key-vault-configuration.md * Update key-vault-configuration.md * Update key-vault-configuration.md * Update key-vault-configuration.md * Update key-vault-configuration.md * Minor updates * Minor update * Update the doc ms.date * Minor update
2017-02-14 04:03:08 +08:00
* [Azure Key Vault configuration provider](xref:security/key-vault-configuration)