Closed rinkeb closed 5 years ago
I think you can accomplish what you want by explicitly providing a file name on the config provider. If you set up a custom provider you can just give it a file name or you can pass the filename as part of the Initialize() call.
Something like this:
var conf = new DbResourceConfiguration();
conf.Initialize(new ConfigurationFileConfigurationProvider<DbResourceConfiguration>()
{
ConfigurationFile = "DbResourceConfiguration.config"
});
Ok, that works partially. The specified config file is indeed opened by the DbResourceConfiguration class, but then parsing results in an exception:
Expression must evaluate to a node-set.
Apparently the xml parser does not like xml fragments. I could add an xml declaration to that external config file as well, but all together this is too non-standard to my taste. I'll just stick with my workaround and avoid config writing by ensuring my config file is not missing any entries.
Do you need the file to be in a specific format? If not, remove the file and data and let the library create it.
I can't recall the details off the top of my head - we write the XML file using standard DOM parsing, but if I remember correctly a configSource file should be a full configuration document. It shouldn't be just a fragment. Maybe your format is not actually valid?
Official documentation is a little sparse, but as far as i can see the external config file referenced by configSource should only contain the section element with the desired content for that section, without an xml declaration.
But indeed, a better idea is to let the application generate it. I tried the following:
Executed code in Owin Startup:
1 var conf = new DbResourceConfiguration();
2 var resourceConfig = System.IO.Path.Combine(
new System.IO.FileInfo(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile).DirectoryName, "Customer\\dbResourceProvider.config");
3 conf.Initialize(new ConfigurationFileConfigurationProvider<DbResourceConfiguration>()
4 {
5 ConfigurationFile = resourceConfig
6 });
Results:
Looks like some work should be postponed to the Initialize method?
@rintje - Can you do me a favor and post the exact config you are trying to run so I can repro your scenario. I'll try to look at this tonight or tomorrow. There are few other minor tweaks that have to be made.
No problem. I've sent you an email with my configs, project file and nuget package config.
@rintje - I have to check to see if the default behavior fires before the provider passed in is used. I think the issue is that the provider is actually running some default behavior internally - not initialize. I have to check.
I think a workaround for that is overriding OnCreateProvider() and setting up your custom provider in that method. That's the recommended way anyway so that you don't have to externalize the configuration information.
More info here: https://github.com/RickStrahl/Westwind.ApplicationConfiguration#configuration-providers
Hi Rick,
In web.config files it is possible to set an optional attribute configSource on a section. This enables the user to store the settings within that section in a separate file. We use this feature to separate customer-specific settings from the common root web config.
When configuring the the db resource provider of the Westwind.Globalization project, we try to follow this strategy as well. For example:
<DbResourceConfiguration configSource="Customer\dbResourceProvider.config" />
This goes well when reading. The settings are properly read from the file specified in the configSource attribute, probably via the built-in .net functionality. However, the provider attempts to write them back to file when any are missing. But instead of writing them to the configSource file (where they came from), they are written as child nodes in the root config file. This breaks the configuration, because child nodes are not allowed for sections where a configSource is specified.
The problem seems to be the Write function at https://github.com/RickStrahl/WestwindToolkit/blob/master/Westwind.Utilities/Configuration/Providers/ConfigurationFileConfigurationProvider.cs#L327 , which calls WriteConfigurationValue on the DOM of the root web config.
The workaround is to ensure all expected config settings are there so it doesn't have to write at all :-) but i guess being more compliant to the specs would make an improvement to the toolkit .