How to programatically update custom attribute in app config file - c#

My app.config.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
</configSections>
<Something SettingsLocation="D:\test\test\file.json" />
<Something />
</configuration>
I need to update SettingsLocation programatically.
I found this some answers, but it is not clear to me.
Thanks fo help.

Each application has it’s own configuration file, be it a windows based application or web based.
This application configuration file defines information which can be used by application to make decisions, to load some other information or may contain the custom configuration which can be empowered to do anything.
There can also be scenarios where an application may want to change\modify the existing setting in the application configuration file and those changes should not only take effect immediately but should also be persisted.
Possible solution is already shown here

Related

Use App.config with a Custom Section shared between two different projects

Scenario
I have developed a windows service which is configured by its App.config file.
This file contains the information in the standard sections (connectionStrings, appSettings) and in a custom section (sourceTabSection).
In the windows service project i have 4 classes which allow me to get/set the config file content. They are based on what is written in this article: Writing a Custom ConfigurationSection to handle a Collection and i have no problems on using them inside my service.
The problems come when i try to get/set the custom section (with the standard sections i don't have any problems) of the App.config, belong to the Windows service, using another application that in my case is a Windows Form that allows users to view/set parameters for the windows service.
The Windows Form application has the same pack of 4 classes used by the service, in order to handle the App.config.
When the code that get/set custom parameters of Windows Service is excuted on the Windows Form app I get the following error message:
{"An error occurred creating the configuration section handler for sourceTabSection: Could not load type 'DataReportingService.CustomSourceTabSection.SourceTabSection' from assembly 'DataReportingService'."}
The problem is due to this following line of code in the App.config
<section name="sourceTabSection" type="DataReportingService.CustomSourceTabSection.SourceTabSection, DataReportingService"/>
The attribute type of the tag shown above has the following meaning (it's explained here: section Element for configSections):
type="Fully qualified class name, assembly file name, version, culture, public key token"
Following what is written on Writing a Custom ConfigurationSection to handle a Collection article I defined only the first two parameter (Fully qualified class name, assembly file name) of the attribute type. Microsoft documentation (no more maintained) doesn't specify that the other parameters can be not defined, but the example that I followed and others use this approach.
However the point is this phrase about the type attribute on Microsoft documentation:
The assembly file must be located in the same application directory
So, due to this bond, seems to be impossible to handle custom section of an application A from another application B (which has another assembly) using this approach.
So do you know how could I solve this problem?
Windows service - App.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="sourceTabSection" type="DataReportingService.CustomSourceTabSection.SourceTabSection, DataReportingService"/>
</configSections>
<!-- *** CUSTOM SECTION *** -->
<sourceTabSection>
<Tables>
<sourceTab name="TEST" db_conn_str="****"
keep_time="1" scan_frequency_process_rows="1"
scan_frequency_delete_processed_rows="1" />
<sourceTab name="TEST_2" db_conn_str="****"
keep_time="1" scan_frequency_process_rows="1"
scan_frequency_delete_processed_rows="1" />
</Tables>
</sourceTabSection>
<!-- *** STANDARD SECTIONS *** -->
<connectionStrings>
<add name="DB_Target" connectionString="Data Source=192.168.2.2;Initial Catalog=PlantDompe;Persist Security Info=True;User ID=sa;Password=Gf6swML0MXiqbOFuvRDvdg==;"
providerName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
<add key="TAB_ALARMS_TARGET" value="AlarmsProcess" />
<add key="TAB_VALUE_TARGET" value="USER_CHANGES" />
<add key="TAB_LOGINS_TARGET" value="USER_LOGONS" />
<add key="LOG_DIR" value="C:/Users/rossi/Documents/Visual Studio 2017/Projects/DRS_proj/Log/" />
</appSettings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
</startup>
<system.web>
<trust level="Full" />
<webControls clientScriptsLocation="/aspnet_client/{0}/{1}/" />
</system.web>
</configuration>
Ugly solution
If found a work around to this problem by performing the two following steps on the Windows Form application that need to view/set the parameters (custom and no custom) inside the App.config of the Windows Service:
Using visual studio i go to Solution Properties > Application tab, and I change the following values
Assembly name = DataReportingService
Default namespace = DataReportingService
Note: DataReportingService is the name of the window service with the App.config file
Find and replace all the references to old namespace with the new one
In this way I can handle the custom section of the App.config, but honestly it's a really ugly solution and I think that there should be something better.
Thanks #Alex Paven, your comment has helped me to solve this problem!
Here below there are the detailed steps of what I've done:
I moved the 4 classes which handles the Windows service config file in a Class Library project (.NET Framework) called: DRS_CustomConfig.
I changed the namespace of the 4 classes with the following value: DRS_CustomConfig and then I compiled the project.
I linked the external library both in the Windows service project and in Windows Form application
For each class of both projects which need to use the classes contained in the external library I inserted the following piece of code:
using DRS_CustomConfig;
In the App.config of the Windows service I changed the section element as follows:
Old
<section name="sourceTabSection"
type="DataReportingService.CustomSourceTabSection.SourceTabSection,
DataReportingService"/>
New
<section name="sourceTabSection"
type="DRS_CustomConfig.SourceTabSection, DRS_CustomConfig"/>

How to save Application theme name in App.config

In my application user can select any theme to apply. But if he closes application and opens it again, Themes changes doesn't same. I want that these changes should be saved so if user after applying theme will open it again, changes should be saved and apply.
Should I have to save name of theme in app.config or is there any other way to solve this?
I need your suggestions. Thank you.
Try this:
<appSettings>
<add key="Theme" value ="YOUR_COLOR"/>
</appSettings>
and use it in this way in the application:
using System.Configuration;
string myTheme=ConfigurationManager.AppSettings("Theme");
If you're talking about an ASP.NET application - you should read the How To: Apply ASP.NET Themes documentation MSDN.
Basically, in the web.config of your web application, you can define the theme to be used:
<configuration>
<system.web>
<pages theme="ThemeName" />
</system.web>
</configuration>
With this configuration, the ASP.NET web application will automatically use that theme - no manual coding necessary on your side.

Can I store settings in a settings.config file in ASP.NET MVC?

I'm using .NET MVC
I have about 10 properties I want to store in a configuration file (.config etc.), related to environment/deployment stuff, + other things for quick changes without doing dLL deploys.
I'm using Team foundation service for CI builds etc, and my web.config is obviously under version-contrl.
What I'd like to do is have a settings.config (that's not in version control) file to store these, am I able to do this?
Or does it need to be in web.config?
To answer the title question, yes you can store settings in a separate config file, to do so you need to define the configSource property of appSettings element
E.g.
<appSettings configSource="settings.config" />
and in the settings.config file
<?xml version="1.0" encoding="UTF-8"?>
<appSettings>
<add key="settingKey" value="environmentValue" />
</appSettings>
However, for the sake of environment specific settings, you may want to look at config transforms. Setting up a transform config for each environment then deploying to that environment with the specified build configuration.
E.g. Web.Dev.config (provided you have setup a 'Dev' build configuration)
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<appSettings>
<add key="settingKey"
value="devEnvironmentValue"
xdt:Transform="SetAttributes" xdt:Locator="Match(key)"/>
</appSettings>
</configuration>
More details of build configuration and config transforms here: http://msdn.microsoft.com/en-us/library/dd465318(v=vs.100).aspx
Or you could take advantage of TFS features and parameterize the environment variables, I don't have a lot of experience with this, but the following should help: http://ig.obsglobal.com/2013/02/tfs-and-continuous-deployment-part-4-parameterized-deployments/

How to prevent inheritance for web.config file for "configSections"?

I have following in my parent web applications config file
<configuration>
<configSections>
<sectionGroup name="testmodule">
<section name="testmodule" type="RewriteModule.RewriteModuleSectionHandler, RewriteModule"/>
</sectionGroup>
</configSections>
</configuration>
i want to prevent child subfolders from inheriting this config section where should i put
<location path="." inheritInChildApplications="false">, since config sections should be first child element of configuration file
This has been answered a couple of times on SO, but incorrectly in my opinion.
The docs, are pretty clear (1)(2):
The following example shows how to use
this attribute in a configuration file
to specify that the settings defined
in the location element for the root
of a Web site should not be inherited
by child applications:
The InheritInChildApplications
property applies only to
location-specific configuration
settings.
To answer your question, this should suffice:
<configuration>
...
<sectionGroup name="testmodule">
<section name="testmodule" type="RewriteModule.RewriteModuleSectionHandler, RewriteModule"/>
</sectionGroup>
...
<location path="." inheritInChildApplications="false">
<testModule>
....
</testModule>
</location>
(1) - http://msdn.microsoft.com/en-us/library/system.configuration.sectioninformation.inheritinchildapplications.aspx
(2) - http://msdn.microsoft.com/en-us/library/ms178692.aspx
Seems to be no solution for this currently, should avoid using conflicting section groups in web.config file.
If you use a different name in the conflicting child section it will not clash with the parent and you can reference both sections in their respective web.config files using the different names..
its not perfect but its a work around i've used with success....
We're getting errors about duplicate configuration directives on the one of our apps.
After investigation it looks like it's because of this issue.
In brief, our root website is ASP.NET 3.5 (which is 2.0 with specific libraries added), and we have a subapplication that is ASP.NET 4.0.
web.config inheritance causes the ASP.NET 4.0 sub-application to inherit the web.config file of the parent ASP.NET 3.5 application.
However, the ASP.NET 4.0 application's global (or "root") web.config, which resides at C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\web.config and C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\web.config (depending on your bitness), already contains these config sections.
The ASP.NET 4.0 app then tries to merge together the root ASP.NET 4.0 web.config, and the parent web.config (the one for an ASP.NET 3.5 app), and runs into duplicates in the node.
The only solution I've been able to find is to remove the config sections from the parent web.config, and then either
Determine that you didn't need them in your root application, or
Upgrade the parent app to ASP.NET 4.0 (so it gains access to the root web.config's configSections)
i have the same situation than you as my root Application is using an AppPool of .net 2.0 and child AppPool is .Net 4.0. I solved using the suggestion in "Entry has already been added" - Two Separate App Pools, by setting both AppPools to enableConfigurationOverride="false" it works like a charm.

C# How to redirect assembly loading using application config file

I have an assembly with few versions registered in the GAC. Now, I want one of my clients which uses this assembly (version 1.3) to point to the newest version (1.4) without opening the source and recompiling the client.
I saw an article demonstrating a technique for doing so using the application config file (winform application)
here is the config file content :
<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:asm="urn:schemas-microsoft-com:asm.v1">
<runtime>
<asm:assemblyBinding>
<!-- one dependentAssembly per unique assembly name -->
<asm:dependentAssembly>
<asm:assemblyIdentity
name="MyFacade"
publicKeyToken="c9c18e16df1654e0" />
<!-- one bindingRedirect per redirection -->
<asm:bindingRedirect oldVersion="1.3.0.0"
newVersion="1.4.0.0" />
</asm:dependentAssembly>
</asm:assemblyBinding>
</runtime>
</configuration>
As you can see, there is a binding redirect from version 1.3.0.0 to 1.4.0.0 for assembly named MyFacade.
Now, there's only a Minor issue with this approach. It doesn't work :)
I'm sure it's something with my code.
Any suggestions?
Thanks,
Adi Barda
first, this is the best source I've found about this subject. There are some differences, for example, they are not using the asm: namespace, and also, you might want to disable the publisher policy by adding <publisherPolicy apply="no" /> as described in the article.
In a previous project we did, we needed even more control, so we needed to catch the AppDomain.AssemblyResolve Event and route to any assembly we wanted. Here you can find more informations about the concept. You'd have to manipulate your app once, though.

Categories