I want to make a library that will be used by either an exe (app.config) or a website (web.config). If I create a custom configuration section, and load it using
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
CustomSection section = config.Sections.OfType<CustomSection>().FirstOrDefault();
it won't run on web site. It throws a exePath must be specified when not running inside a stand alone exe. exception, since it's not an exe. I can use something like:
CustomSection db = (CustomSection )ConfigurationSettings.GetConfig("CustomSection");
But that relies on the section being properly named. Is there a way to get all the sections and iterate through them?
Related
I created a new .NET Core web project using Visual Studio and integrated Serilog. It reads settings from the appsettings.json (via .UseSerilog((ctx, config) => { config.ReadFrom.Configuration(ctx.Configuration); })).
In the appsettings.json, the path to write the log is specified at Serilog/WriteTo/Args/pathFormat. If I set that value to log.txt, it will attempt to write the file to `c:\program files\iisexpress\log.txt'.
How can I get it to write to the content root of my web app?
Ideally, you don't want to write log files to the content root of your web app, since these could end up being accessible over the web, which would be a serious security consideration.
The log file path configuration can include environment variables, so something like %TMP%\log.txt, or a path based on %LOCALAPPDATA% etc. is a good option (as long as the web site's worker process has permission to write to the location).
You can write to a path that's relative to your web app by changing the current directory before setting up the logger:
Environment.CurrentDirectory = AppContext.BaseDirectory;
Or, you can combine these approaches and set your own environment variable to do it:
Environment.SetEnvironmentVariable("BASEDIR", AppContext.BaseDirectory);
Thus the following config:
"%BASEDIR%\logs\log.txt"
I am needing to find away to write to another programs app.config file.
we have a 3rd party application that gets some values from an AppSettings section in its own config. but the only way we can get to change the value is when we call the application and once it runs it does a function which we don't want it to do if it doesn't have the correct values.
We need to encrypt one of the values so what we were think of was creating an application that would save the values in this 3rd party app.config.
saving the values and the encryption aren't a problem its doing it in another applications config file.
Is there a way to set which config file we use or a config path setting?
Regards
Aidan
Thank you for the help with this, I managed to get it done through this code.
string configLocation = string.Format("{0}\\APP.exe.config", Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
ExeConfigurationFileMap map = new ExeConfigurationFileMap();
map.ExeConfigFilename = configLocation;
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
txtEndpoint.Text = config.AppSettings.Settings["ENDPOINT"].Value;
This now allows me to write out the set config file values in the appsettings.
Cheers All.
Aidan
I am having two projects one is basically a Windows service and second is class project in which I am doing my business processing. My App.config file is in Windows service project and in my Class project I am using below
ConfigurationManager.RefreshSection("appsettings");
string scheduledTime = ConfigurationManager.AppSettings["ScheduleTime"];
this setting is in my appsettings section of config file
I am using RefreshSection and also updating my app.config value in windows service project but its not getting updated at run time in my class project.
What is the catch in this ?
I'm having a little trouble myself with something similar, however I did come across something for AppSettings. Give this a shot:
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
ConfigurationManager.RefreshSection(config.AppSettings.SectionInformation.Name);
I think appsettings should be appSettings
If you want to get latest value use this code:
var appSettings = ConfigurationManager.OpenExeConfiguration(System.Reflection.Assembly.GetEntryAssembly().Location).AppSettings;
var mySetting = appSettings.Settings["keyOfSetting"].Value;
remember every time you need latest value, must use two line of code in same place!
I am using Entity Framework. The connection string is currently saved in the app.config file, which by default creates a new file called APPLICATION_NAME.exe.config and copies it to the output folder when building.
Now I don't want my connection string to be visible to the world when I am creating applications, so one way is to create another config file as a resource and reference it in the application.
EDIT:
I am developing using WPF, now is there any special configuration for it doing the below:
How to register an embedded config file in the application ?
Normally when you create your own DbContext, you pass the connection string like this
public MyDBContext() : base("name=Connection_String_Name_In_AppConfig")
so how to tell the DbContext classes to take the connection string from the newly created config file?
Q1. How to register an embedded config file in the Application
You do not. But nothing stops you do "program" code that takes your own configuration information from wherever you want and uses that.
Q2. How to tell DBContext classes to take the DB connection from the newly created config
file ?
You do not. But you can actually pass in an code created connection toe a DbCOntext, in case you did not see that in the documentation.
And seriously, NOTHING in here has ANY relationship to WPF, so that tag you added is just not a good smart move.
To embed a file into the assembly, select the file in the solution explorer and go to Property window then select Build Action as 'Embedded Resource' and Copy to Output Directory as 'Do not copy'. This way the XML config file will get embedded in the assembly.
Now in your Host application(here WPF), you can read the resource file content and then pass the connection string data to your DBContext.
Example to read embedded file from the assembly:
private const string strFileName = “XMLFile.config”;
var assembly = Assembly.GetExecutingAssembly();
var stream = assembly.GetManifestResourceStreamthis.GetType(), strFileName);
var doc = new XmlDocument();
try
{
if (stream == null)
{
throw new FileNotFoundException(“Couldnot find embedded mappings resource file.”, strFileName);
}
doc.Load(stream);
}
catch (Exception ex)
{
throw ex;
}
Hope this will help you
I have a sample application hosted on Github that exactly does what you want.
I have an application that encrypts a section in the configuration file. In the first time that I try to read the encrypted section from the config file I get an error message: "Unrecognized attribute 'configProtectionProvider'. Note that attribute names are case-sensitive. "
config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
// Get the section in the file.
ConfigurationSection section = config.GetSection("EncryptedSection");
if (section != null)
{
// Protect the section.
section.SectionInformation.ProtectSection("RsaProtectedConfigurationProvider");
section.SectionInformation.ForceSave = true;
// Save the change.
config.Save(ConfigurationSaveMode.Modified);
}
ConfigurationManager.RefreshSection("EncryptedSection");
Properties.Settings.Default.Reset();
//This is the part where I read the encrypted section:
ConfigurationManager.RefreshSection("EncryptedSection");
System.Collections.IDictionary HSMMasterKeyConfig = (System.Collections.IDictionary)System.Configuration.ConfigurationManager.GetSection("EncryptedSection");
This only happens in the first time that I try to read the encrypted section. I have noticed that the .config file is getting updated immediately after the first save but from some reason I need to restart the application in order to use the encrypted section.
Have you read through this...
http://bytes.com/groups/net/521818-configurationerrorexception-when-reading-protected-config-section
... as it appears to be a conversation involving an MSFT support engineer that directly maps to your situation.
The best way to do this will be to encrypt the app.config sections during installation only. Add an installer class to your project and override the Install method in the class. In this method you should perform the Encryption. You must call base.Install at the end of your overridden Install method. In the Setup Project goto Custom Actions and locate the Install custom action to be pointed with Your Project output [exe or assembly] which contains the definition of your Installer class implementation. This way it will Encrypt your app.Config sections during an installation straight and you will not face this problem. The application will automatically use DPAPI provider to read/write through sections or settings.
For your reference the issue was that the process that was trying to encrypt the config section didn't have admin rights. I added this process to the administrators group and that solved it.
I just ran into the same problem today. Normally, whenever I start an application where the config is in encrypted I always check the config on startup to determine if it's protected. If not the it I follow the standard SectionInformation.ProtectSection method. This is always my first step but today for some reason I decided to reference something from the config before I performed my protection check and got the "Unrecognized attribute 'configProtectionProvider'. Note that attribute names are case-sensitive. " error. All you have to do is run protection code before you reference the config within your normal code and you will no longer have the error.
Try running your Exe in seperate Application Domain. Once your application is loaded in the new AppDomain, check if the Sections are encrypted or not. If not then Encrypt the section and trigger the AppDomain to unload and reload with your executable again.