Skip to content

Commit 93a718d

Browse files
Fix FAQ formatting
1 parent a2e7350 commit 93a718d

1 file changed

Lines changed: 128 additions & 123 deletions

File tree

docs/FAQ.md

Lines changed: 128 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -1,156 +1,161 @@
11
# MicrosoftConfigurationBuilders FAQ
22

3-
TODO - search for 'expand'
43
We get a lot of questions about `KeyValueConfigBuilders` - and Configuration Builders in general. Here are
54
some of the most frequent along with answers that are hopefully helpful.
65

7-
6+
<a name="expand"></a>
87
<details>
9-
<summary><a name="expand"><b>Why did you get rid of 'Expand' mode?</b></a></summary>
10-
11-
Because 'Expand' mode operated in the 'ProcessRawXml' phase of configuration building, while the other
12-
modes all operate in 'ProcessConfigurationSection.' It was a bit of a balancing act trying to develop
13-
features that work across both phases - a challenge which is sometimes quite difficult given the lack of
14-
information we have about the section we are processing in 'ProcessRawXml.'
8+
<summary><b>Why did you get rid of 'Expand' mode?</b></summary>
159

16-
For example, V3 of these builders tries to accomodate 'ConfigurationManager.OpenConfiguration()'
17-
scenarios where apps want to read a config file that is not their own. In these cases, we need to
18-
know information about the file and section we are processing that we just can't know in the
19-
'ProcessRawXml' phase. Another example is the [parameters from appSettings](KeyValueConfigBuilders.md#appsettings-parameters)
20-
feature which was disabled in 'Expand' mode while processing the appSettings section, but can
21-
still be used somewhat functionally when executing any of the modes that operate in 'ProcessConfigurationSection.'
22-
23-
To make things simpler across the board, 'Expand' mode was replaced with 'Token' mode which should
24-
operate in a fairly similar manner with the added benefit of being less prone to producing invalid
25-
XML to muck things up. :smiley:
10+
> Because 'Expand' mode operated in the 'ProcessRawXml' phase of configuration building, while the other
11+
> modes all operate in 'ProcessConfigurationSection.' It was a bit of a balancing act trying to develop
12+
> features that work across both phases - a challenge which is sometimes quite difficult given the lack of
13+
> information we have about the section we are processing in 'ProcessRawXml.'
14+
>
15+
> For example, V3 of these builders tries to accomodate 'ConfigurationManager.OpenConfiguration()'
16+
> scenarios where apps want to read a config file that is not their own. In these cases, we need to
17+
> know information about the file and section we are processing that we just can't know in the
18+
> 'ProcessRawXml' phase. Another example is the [parameters from appSettings](KeyValueConfigBuilders.md#appsettings-parameters)
19+
> feature which was disabled in 'Expand' mode while processing the appSettings section, but can
20+
> still be used somewhat functionally when executing any of the modes that operate in 'ProcessConfigurationSection.'
21+
>
22+
> To make things simpler across the board, 'Expand' mode was replaced with 'Token' mode which should
23+
> operate in a fairly similar manner with the added benefit of being less prone to producing invalid
24+
> XML to muck things up. :smiley:
2625
</details>
2726
27+
<a name="newhandler"></a>
2828
<details>
29-
<summary><a name="newhandler"><b>Can you add a `SectionHandler` for section `XYZ?`</b></a></summary>
29+
<summary><b>Can you add a `SectionHandler` for section `XYZ?`</b></summary>
3030

31-
We have included default `SectionHandlers` for `<appSettings>` and `<connectionStrings>` because they
32-
are by far the most commonly used "key/value" config sections. But we introduced the `SectionHandler<T>`
33-
API to allow for more sections to be processed.
34-
35-
We don't currently feel that there are any other sections out there that have enough demand to
36-
warrant including a default section handler in the base package that everybody is required to use.
37-
That does not mean that section handlers for other sections is not ever a valid scenario, and you
38-
are of course welcome and encouraged to leverage the section handler feature if it suits your needs.
39-
That is why we introduced the feature afterall.
31+
> We have included default `SectionHandlers` for `<appSettings>` and `<connectionStrings>` because they
32+
> are by far the most commonly used "key/value" config sections. But we introduced the `SectionHandler<T>`
33+
> API to allow for more sections to be processed.
34+
>
35+
> We don't currently feel that there are any other sections out there that have enough demand to
36+
> warrant including a default section handler in the base package that everybody is required to use.
37+
> That does not mean that section handlers for other sections is not ever a valid scenario, and you
38+
> are of course welcome and encouraged to leverage the section handler feature if it suits your needs.
39+
> That is why we introduced the feature afterall.
4040
</details>
4141
42+
<a name="applicationsettings"></a>
4243
<details>
43-
<summary><a name="applicationsettings"><b>Can you add a `SectionHandler` for the client `ApplicationSettings` section?</b></a></summary>
44+
<summary><b>Can you add a `SectionHandler` for the client `ApplicationSettings` section?</b></summary>
4445

45-
See [above](#newhandler). `ApplicationSettings` is less commonly used. But more problematically, it
46-
isn't really a standard .Net configuration section like it appears to be on first glance. The classes
47-
that support ApplicationSettings provide a strict and strongly typed window into what looks like a
48-
standard configuration section in your app.config file. While we can easily write a section handler
49-
for the `ClientSettingsSection` ([example](../samples/SampleSectionHandlers/ClientSettingsSectionHandler.cs))
50-
it won't integrate into the ApplicationSettings framework seamlessly like one might expect. The
51-
ApplicationSetting framework has already determined the number and names (including casing, which
52-
is problematic in 'Greedy' mode) of all the settings it will present before the base configuration
53-
system even gets a crack at reading from the config file. So you can't *add* new values with 'Greedy'
54-
mode, and you can't override existing values in 'Greedy' mode if you don't properly match
55-
casing - despite the fact that ApplicationSettings is supposed to be case-insensitive.
56-
57-
If you wish, you can use the [sample section handler](../samples/SampleSectionHandlers/ClientSettingsSectionHandler.cs)
58-
to process ApplicationSettings in your application, but know that the use case is rather limited.
59-
It will work in 'Strict' mode... and maybe require some prodding to force the ApplicationSettings
60-
framework to forget the settings it's seen before and decide to look back into the config file to
61-
get new values.
62-
63-
You can read more about the architecture of the AppliationSettings framework [here](https://docs.microsoft.com/en-us/dotnet/desktop/winforms/advanced/application-settings-architecture?view=netframeworkdesktop-4.8)
64-
to see how it builds layers on top of the standard config system that often obscure any changes or
65-
additional settings that appear in the `ClientSettingsSection` but won't be seen in
66-
`MyApp.Properties.Settings`. That set of articles is also a good starting point for learning
67-
about `SettingsProvider` and how that might be leveraged to accomplish configuration injection
68-
through a different mechanism in the case when applications must use ApplicationSettings.
46+
> See [above](#newhandler). `ApplicationSettings` is less commonly used. But more problematically, it
47+
> isn't really a standard .Net configuration section like it appears to be on first glance. The classes
48+
> that support ApplicationSettings provide a strict and strongly typed window into what looks like a
49+
> standard configuration section in your app.config file. While we can easily write a section handler
50+
> for the `ClientSettingsSection` ([example](../samples/SampleSectionHandlers/ClientSettingsSectionHandler.cs))
51+
> it won't integrate into the ApplicationSettings framework seamlessly like one might expect. The
52+
> ApplicationSetting framework has already determined the number and names (including casing, which
53+
> is problematic in 'Greedy' mode) of all the settings it will present before the base configuration
54+
> system even gets a crack at reading from the config file. So you can't *add* new values with 'Greedy'
55+
> mode, and you can't override existing values in 'Greedy' mode if you don't properly match
56+
> casing - despite the fact that ApplicationSettings is supposed to be case-insensitive.
57+
>
58+
> If you wish, you can use the [sample section handler](../samples/SampleSectionHandlers/ClientSettingsSectionHandler.cs)
59+
> to process ApplicationSettings in your application, but know that the use case is rather limited.
60+
> It will work in 'Strict' mode... and maybe require some prodding to force the ApplicationSettings
61+
> framework to forget the settings it's seen before and decide to look back into the config file to
62+
> get new values.
63+
>
64+
> You can read more about the architecture of the AppliationSettings framework [here](https://docs.microsoft.com/en-us/dotnet/desktop/winforms/advanced/application-settings-architecture?view=netframeworkdesktop-4.8)
65+
> to see how it builds layers on top of the standard config system that often obscure any changes or
66+
> additional settings that appear in the `ClientSettingsSection` but won't be seen in
67+
> `MyApp.Properties.Settings`. That set of articles is also a good starting point for learning
68+
> about `SettingsProvider` and how that might be leveraged to accomplish configuration injection
69+
> through a different mechanism in the case when applications must use ApplicationSettings.
6970
</details>
7071
72+
<a name="azureappservices"></a>
7173
<details>
72-
<summary><a name="azureappservices"><b>Do ConfigBuilders break the 'Application Settings' feature of Azure AppServices?</b></a></summary>
74+
<summary><b>Do ConfigBuilders break the 'Application Settings' feature of Azure AppServices?</b></summary>
7375

74-
Maybe a little? It does appear that adding a 'configBuilders' tag to your 'appSettings' or 'connectionStrings'
75-
sections confuses the injection logic for the Azure AppServices "Application Settings" feature. I do not
76-
have any insight as to why that is other than to say that the two features "grew up" contemporaneously, so
77-
they were probably not aware that configBuilders could exist.
78-
79-
But all is not lost. The "Application Settings" feature injects all it's values into the environment of
80-
the service. So while using ConfigBuilders might interfere with the automatic injection of those values,
81-
you can also use ConfigBuilders to pull those values back in. See [this issue comment](#133#issuecomment-1049520479)
82-
for more details.
76+
> Maybe a little? It does appear that adding a 'configBuilders' tag to your 'appSettings' or 'connectionStrings'
77+
> sections confuses the injection logic for the Azure AppServices "Application Settings" feature. I do not
78+
> have any insight as to why that is other than to say that the two features "grew up" contemporaneously, so
79+
> they were probably not aware that configBuilders could exist.
80+
>
81+
> But all is not lost. The "Application Settings" feature injects all it's values into the environment of
82+
> the service. So while using ConfigBuilders might interfere with the automatic injection of those values,
83+
> you can also use ConfigBuilders to pull those values back in. See [this issue comment](#133#issuecomment-1049520479)
84+
> for more details.
8385
</details>
8486
87+
<a name="iisschema"></a>
8588
<details>
86-
<summary><a name="iisschema"><b>Why does IIS/inetmgr complain about configBuilders?</b></a></summary>
89+
<summary><b>Why does IIS/inetmgr complain about configBuilders?</b></summary>
8790

88-
Because IIS config tools are old and cranky, just like the old .Net config system wanted them to be. :smiling_imp:
89-
90-
The old .Net config system is supposed to be quite rigid and super-strongly typed. So when IIS developed
91-
tools to work with config, they took steps to ensure they didn't break folks by creating invalid configuration.
92-
In particular, they decided to use XML schema's to ensure the XML they save is on the up-and-up. (Just
93-
like Visual Studio does. But Visual Studio gets updated quite a bit more frequently than IIS tools and
94-
has a lower bar for fixing nagging bugs that have a workaround - and was therefore better equipped to
95-
change with the times when .Net config added new features and sections. Also, failing schema validation
96-
in Visual Studio simply resulted in red squiggles instead of error dialogs. :frowning:)
97-
98-
The workaround is really quite simple, but it isn't something we can do in these packages. As suggested
99-
in #126, simply add a schema file for IIS to help it understand that configBuilders are ok on some
100-
sections.
101-
102-
`%systemroot%\system32\inetsrv\config\schema\configBuilders_schema.xml`
103-
```xml
104-
<configSchema>
105-
<sectionSchema name="appSettings">
106-
<attribute name="configBuilders" type="string"/>
107-
</sectionSchema>
108-
<sectionSchema name="connectionStrings">
109-
<attribute name="configBuilders" type="string"/>
110-
</sectionSchema>
111-
</configSchema>
112-
```
91+
> Because IIS config tools are old and cranky, just like the old .Net config system wanted them to be. :smiling_imp:
92+
>
93+
> The old .Net config system is supposed to be quite rigid and super-strongly typed. So when IIS developed
94+
> tools to work with config, they took steps to ensure they didn't break folks by creating invalid configuration.
95+
> In particular, they decided to use XML schema's to ensure the XML they save is on the up-and-up. (Just
96+
> like Visual Studio does. But Visual Studio gets updated quite a bit more frequently than IIS tools and
97+
> has a lower bar for fixing nagging bugs that have a workaround - and was therefore better equipped to
98+
> change with the times when .Net config added new features and sections. Also, failing schema validation
99+
> in Visual Studio simply resulted in red squiggles instead of error dialogs. :frowning:)
100+
>
101+
> The workaround is really quite simple, but it isn't something we can do in these packages. As suggested
102+
> in #126, simply add a schema file for IIS to help it understand that configBuilders are ok on some
103+
> sections.
104+
>
105+
> `%systemroot%\system32\inetsrv\config\schema\configBuilders_schema.xml`
106+
> ```xml
107+
> <configSchema>
108+
> <sectionSchema name="appSettings">
109+
> <attribute name="configBuilders" type="string"/>
110+
> </sectionSchema>
111+
> <sectionSchema name="connectionStrings">
112+
> <attribute name="configBuilders" type="string"/>
113+
> </sectionSchema>
114+
> </configSchema>
115+
> ```
113116
114117
</details>
115118
119+
<a name="windowscontainers"></a>
116120
<details>
117-
<summary><a name="windowscontainers"><b>My config builder isn't working in my Windows container.</b></a></summary>
121+
<summary><b>My config builder isn't working in my Windows container.</b></summary>
118122
119-
That's a statement, not a question. But here's a likely explanation.
120-
121-
Windows containers only modify the environment block of the EntryPoint process. So if your application
122-
is running as a service (like IIS/ASP.Net apps) or some other process not directly created by the
123-
EntryPoint, any environment variables set when starting the container will not be visible to your
124-
app.
125-
126-
To work around this issue, [ASP.Net](https://github.com/microsoft/dotnet-framework-docker/tree/main/src/aspnet)
127-
and [IIS](https://github.com/microsoft/iis-docker) container images rely on a `ServiceMonitor.exe`
128-
utility to be the entry point for the container, and this utility proactively modifies the environment
129-
of the worker process with any additional environment variables passed to docker run.
130-
131-
For IIS/ASP.Net workloads, do try to use an IIS/ASP.Net derived container that uses `ServiceMonitor.exe.`
132-
For other workloads, try making your app the EntryPoint, or try a similar approach to how IIS/ASP.Net
133-
handle this... possibly even leveraging [ServiceMonitor.exe](https://github.com/Microsoft/IIS.ServiceMonitor)
134-
itself.
123+
> That's a statement, not a question. But here's a likely explanation.
124+
>
125+
> Windows containers only modify the environment block of the EntryPoint process. So if your application
126+
> is running as a service (like IIS/ASP.Net apps) or some other process not directly created by the
127+
> EntryPoint, any environment variables set when starting the container will not be visible to your
128+
> app.
129+
>
130+
> To work around this issue, [ASP.Net](https://github.com/microsoft/dotnet-framework-docker/tree/main/src/aspnet)
131+
> and [IIS](https://github.com/microsoft/iis-docker) container images rely on a `ServiceMonitor.exe`
132+
> utility to be the entry point for the container, and this utility proactively modifies the environment
133+
> of the worker process with any additional environment variables passed to docker run.
134+
>
135+
> For IIS/ASP.Net workloads, do try to use an IIS/ASP.Net derived container that uses `ServiceMonitor.exe.`
136+
> For other workloads, try making your app the EntryPoint, or try a similar approach to how IIS/ASP.Net
137+
> handle this... possibly even leveraging [ServiceMonitor.exe](https://github.com/Microsoft/IIS.ServiceMonitor)
138+
> itself.
135139
</details>
136140
141+
<a name="vstyperes"></a>
137142
<details>
138-
<summary><a name="vstyperes"><b>Why do I get an error in Visual Studio when I switch my web app to use IIS instead of IISExpress?</b></a></summary>
143+
<summary><b>Why do I get an error in Visual Studio when I switch my web app to use IIS instead of IISExpress?</b></summary>
139144
140-
Many reasons. The gist of the situation is this... When you switch your web application to run in IIS
141-
instead of IISExpress, Visual Studio tries to read your config file to parse connection strings. I
142-
believe it's looking for 'LocalDB', but that's not really important. Your web app's config file is
143-
obviously not part of the process configuration for devenv.exe, so VS opens it via
144-
`ConfigurationManager.OpenConfiguration()` or something similar. Prior to V3, this was likely to
145-
result in failures in many of these key/value config builders if they were applied to the
146-
`<connectionStrings>` section.
147-
148-
In V3, we handle the `ConfigurationManager.OpenConfiguration()` scenario better, but we can still
149-
get tripped up by the insanely complicated way Visual Studio manages reference binding. As a result,
150-
there may be version mis-matches when trying to load some builders. The Azure builders seem particularly
151-
vulnerable to this. I haven't found a good way to deal with this.
152-
153-
**However,** even though the error appears in a scary dialog box, it does not affect the behavior of
154-
your application. When running/debugging your app on local IIS, the config builders are still able to
155-
execute as expected.
145+
> Many reasons. The gist of the situation is this... When you switch your web application to run in IIS
146+
> instead of IISExpress, Visual Studio tries to read your config file to parse connection strings. I
147+
> believe it's looking for 'LocalDB', but that's not really important. Your web app's config file is
148+
> obviously not part of the process configuration for devenv.exe, so VS opens it via
149+
> `ConfigurationManager.OpenConfiguration()` or something similar. Prior to V3, this was likely to
150+
> result in failures in many of these key/value config builders if they were applied to the
151+
> `<connectionStrings>` section.
152+
>
153+
> In V3, we handle the `ConfigurationManager.OpenConfiguration()` scenario better, but we can still
154+
> get tripped up by the insanely complicated way Visual Studio manages reference binding. As a result,
155+
> there may be version mis-matches when trying to load some builders. The Azure builders seem particularly
156+
> vulnerable to this. I haven't found a good way to deal with this.
157+
>
158+
> **However,** even though the error appears in a scary dialog box, it does not affect the behavior of
159+
> your application. When running/debugging your app on local IIS, the config builders are still able to
160+
> execute as expected.
156161
</details>

0 commit comments

Comments
 (0)