App.config doesn't save some changes after app relaunch - c#

I have a next App.config file:
<configuration>
<configSections>
<sectionGroup name="UserSettingsGroup">
<section name="dbConnectionString" type="System.Configuration.ConnectionStringsSection" />
<section name="reportsFolderSettings" type="System.Configuration.DictionarySectionHandler" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
</startup>
<UserSettingsGroup>
<dbConnectionString>
<add name="Host" providerName="System.Data.sqlclient" connectionString="localhost" />
<add name="Port" providerName="System.Data.sqlclient" connectionString="3050" />
........
........ etc.
</dbConnectionString>
<reportsFolderSettings>
<add key="ReportsFolder" value="C:\" />
</reportsFolderSettings>
</UserSettingsGroup>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<system.data>
<DbProviderFactories>
<remove invariant="FirebirdSql.Data.FirebirdClient" />
<add name="FirebirdClient Data Provider" invariant="FirebirdSql.Data.FirebirdClient" description=".NET Framework Data Provider for Firebird" type="FirebirdSql.Data.FirebirdClient.FirebirdClientFactory, FirebirdSql.Data.FirebirdClient" />
</DbProviderFactories>
</system.data>
And then I made some changes in runtime in my app's settings (I've changed the connections strings and the path for saving app's reports) and for applying them I used this code:
private void SaveSettings() {
ExeConfigurationFileMap configMap = new ExeConfigurationFileMap();
Configuration config = ConfigurationManager.OpenExeConfiguration(System.Reflection.Assembly.GetEntryAssembly().Location);
ConnectionStringsSection connectionSettings = (ConnectionStringsSection)config.SectionGroups.Get("UserSettingsGroup").Sections.Get("dbConnectionString");
connectionSettings.ConnectionStrings["Host"].ConnectionString = txtServer.Text;
connectionSettings.ConnectionStrings["Port"].ConnectionString = txtPort.Text;
connectionSettings.ConnectionStrings["DbPath"].ConnectionString = txtDBPath.Text;
connectionSettings.ConnectionStrings["User"].ConnectionString = txtUser.Text;
connectionSettings.ConnectionStrings["Password"].ConnectionString = txtPassword.Text;
connectionSettings.ConnectionStrings["Charset"].ConnectionString = cboCharset.Text;
Hashtable sectionReportsFolder = ConfigurationManager.GetSection(config.SectionGroups.Get("UserSettingsGroup").Sections.
Get("reportsFolderSettings").SectionInformation.SectionName) as Hashtable;
sectionReportsFolder.Clear();
sectionReportsFolder.Add("ReportsFolder", tbo_reportfolder.Text);
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("dbConnectionString");
ConfigurationManager.RefreshSection("reportsFolder");
}
At first glance, everything works well - I see the changes while my app is working but for some reason the app doesn't save the "reportsFolderSettings" and after relaunch I see only default value "C:\".
P.S I launch the app from .exe from "\bin\release" folder, NOT from Visual studio.

OK, I recreated Your problem and I had the same problem ; )
The problem is DictionarySectionHandler supports only reading values
This is not direct answer to Your question but it works
To work I do this:
I change type of section from:
<section name="reportsFolderSettings" type="System.Configuration.DictionarySectionHandler" />
to use the AppSettingsSection
<section name="reportsFolderSettings" type="System.Configuration.AppSettingsSection" />
Then I change:
var sectionReportsFolder = config.SectionGroups["UserSettingsGroup"].Sections["reportsFolderSettings"] as AppSettingsSection;
sectionReportsFolder.Settings.Clear();
sectionReportsFolder.Settings.Add("ReportsFolder", tbo_reportfolder.Text);
And then everything is work good. I tested this.

Related

Custom section in App.Config, ConfigurationManager stops working

I have created a console app in c# that reads information from App.config. if i add things in appSettings section, i can acces them and it works, but as soon as i add some custom sections i cant read anything from it. I am using ConfigurationManager, and i have the reference for it included.
My app config looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<appSettings>
<add key="overwriteBackupFiles" value="False"/>
<add key="path" value="c:\temp"/>
</appSettings>
<ImageFormatsINeed>
<add key="type1" value="width=180&height=180"></add>
<add key="type2" value="width=220&height=220"></add>
<add key="type3" value="width=500&height=500"></add>
</ImageFormatsINeed>
</configuration>
and i am trying to acces those information like this:
string path = ConfigurationManager.AppSettings["path"];
var settings = ConfigurationManager.GetSection("ImageFormatsINeed");
When i didnt have the ImageFormatsINeed section i could get the path from AppSettings and it was working. But as soon as i added my ImageFormatsINeed section, everything stops working.
Now my question is how can i add custom sections in app.config that it will work, or should i just read my ImageInformation from some custom xml file or config file?
You have to use the tag <configSections> at the top in your app.config, for this case you should use the type AppSettingsSection
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="ImageFormatsINeed" type="System.Configuration.AppSettingsSection" />
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<appSettings>
<add key="overwriteBackupFiles" value="False"/>
<add key="path" value="c:\temp"/>
</appSettings>
<ImageFormatsINeed>
<add key="type1" value="width=180&height=180"></add>
<add key="type2" value="width=220&height=220"></add>
<add key="type3" value="width=500&height=500"></add>
</ImageFormatsINeed>
</configuration>
Then in your C# code:
NameValueCollection settings_section = ConfigurationManager.GetSection("ImageFormatsINeed") as NameValueCollection;
Console.WriteLine(settings_section["type1"]);

MS Unit test Data Source cannot be found in test configuration settings

I've a data source details defined in app.config file in a test project, but when I used the data source name in a test function it's not executing it rather throwing error like "Data source 'MyDataSourceName' cannot be found in test configuration settings".
Exception:
My Data Source in app.config file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="UnitTestConfiguration" type="Microsoft.VisualStudio.TestTools.UnitTesting.TestConfigurationSection, Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
</configSections>
<connectionStrings>
<add name="DataSourceConnection" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\DataSource;Extended Properties='text;HDR=Yes;FMT=Delimited'"
providerName="System.Data.OleDb" />
</connectionStrings>
<UnitTestConfiguration>
<dataSources>
<add name="TargetDataSource" connectionString="DataSourceConnection" dataTableName="UserData#CSV" dataAccessMethod="Sequential"/>
</dataSources>
</UnitTestConfiguration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
</configuration>
My test function:
[DataSource("TargetDataSource")]
[TestMethod]
public void UserValidationTest()
{
}

'Option not supported' error when using SQL Server with MySQL

I'm trying to retrieve data from both MySQL and SQL Server on the same console application. I manage to retrieve data from MySQL, however when I trying to retrieve data from SQL Server, I got System.ArgumentException: 'Option not supported. Parameter name: multipleactiveresultsets' error.
The following is my app.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<connectionStrings>
<add name="MySQLDb" providerName="MySql.Data.MySqlClient" connectionString="server=localhost;port=3306;database=sakila;uid=some_user;password=some_password"/>
<add name="SQLDb" providerName="System.Data.SqlClient" connectionString="data source=USER-PC\SQLEXPRESS;initial catalog=MyDatabase;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"/>
</connectionStrings>
<entityFramework codeConfigurationType="MySql.Data.Entity.MySqlEFConfiguration, MySql.Data.Entity.EF6">
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework"/>
<providers>
<provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6"/>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer"/>
</providers>
</entityFramework>
</configuration>
And my C#:
#region MySQL.
{
var dbContext = new MySQLDb();
var dbSet = dbContext.Set<Actor>();
var actors = dbSet.ToList();
}
#endregion
#region SQLServer.
{
var dbContext = new SQLDb();
var dbSet = dbContext.Set<User>();
var users = dbSet.ToList(); // <-- Throw exception.
}
#endregion
If I disable entityFramework section in app.config and MySQL code block in my C# code, I can retrieve data from SQL Server without any issue.
Version info
MySQL.Data.Entity 6.10.8
NET Framework 4.6.1
Any idea?
Update 1
Found out that the connection type for MySQLDb is MySql.Data.MySqlClient.MySqlConnection, so that works just fine. But when instantiating SQLDb, the connection type is still MySql.Data.MySqlClient.MySqlConnection instead of System.Data.SqlClient.SqlConnection. How should we fix this?
The issue is that we are using MySql.Data.Entity.MySqlEFConfiguration (in the app.config) which set the default connection factory to use MySqlConnectionFactory.
The solution is to use a custom DbConfiguration in place of MySql.Data.Entity.MySqlEFConfiguration to deter from setting the default connection factory.
public class MySQLDbConfiguration : DbConfiguration
{
public MySQLDbConfiguration()
{
SetProviderServices(MySqlProviderInvariantName.ProviderName, new MySqlProviderServices());
SetProviderFactory(MySqlProviderInvariantName.ProviderName, new MySqlClientFactory());
}
}
Declare the instance as readonly somewhere in the code,
private static readonly MySQLDbConfiguration DBConfig = new MySQLDbConfiguration();
and set the configuration PRIOR TO using any EF features
DbConfiguration.SetConfiguration(DBConfig);
And our app.config now becomes
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<connectionStrings>
<add name="MySQLDb" providerName="MySql.Data.MySqlClient" connectionString="server=localhost;port=3306;database=sakila;uid=some_user;password=some_password"/>
<add name="SQLDb" providerName="System.Data.SqlClient" connectionString="data source=USER-PC\SQLEXPRESS;initial catalog=MyDatabase;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"/>
</connectionStrings>
</configuration>
If you're opt to use app.config instead of deriving a custom DbConfiguration, you can do the following
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<!-- Alternative to custom DbConfiguration. -->
<configSections>
<section name = "entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<entityFramework>
<providers>
<provider invariantName = "MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6"/>
</providers>
</entityFramework>
<system.data>
<DbProviderFactories>
<remove invariant = "MySql.Data.MySqlClient" />
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.10.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d"/>
</DbProviderFactories>
</system.data>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<connectionStrings>
<add name="MySQLDb" providerName="MySql.Data.MySqlClient" connectionString="server=localhost;port=3306;database=sakila;uid=some_user;password=some_password"/>
<add name="SQLDb" providerName="System.Data.SqlClient" connectionString="data source=USER-PC\SQLEXPRESS;initial catalog=MyDatabase;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"/>
</connectionStrings>
</configuration>
If you are using asp net 5.0, install the Nuget found here, but first uninstall Mysql.data.

Entity Framework not saving changes to a Local DB

I'm new to C# and Entity Framework and I'm trying to write an application to improve my knowledge.
I think I've set up everything correctly and I don't get any type of error. The problem is that I can not add a new record to localDb in Visual Studio 2017.
Any ideas? Thanks in advance.
Here is my code
private void Save_btn_Click(object sender, EventArgs e)
{
var context = new Database1Entities();
var aMemberdef = new Members()
{
FirstName = Name_txt.Text,
LastName = LastName_txt.Text
};
context.Members.Add(aMemberdef);
context.SaveChanges();
}
and here my app.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework"
type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
requirePermission="false" />
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<connectionStrings>
<add name="Database1Entities"
connectionString="metadata=res://*/EF.Model1.csdl|res://*/EF.Model1.ssdl|res://*/EF.Model1.msl;provider=System.Data.SqlClient;provider connection string="data source=(LocalDB)\MSSQLLocalDB; attachdbfilename=|DataDirectory|\Data\Database1.mdf; initial catalog=Database1; integrated security=True;MultipleActiveResultSets=True;App=EntityFramework""
providerName="System.Data.EntityClient" />
</connectionStrings>
<entityFramework>
<defaultConnectionFactory
type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="System.Data.SqlClient"
type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
</configuration>
I think there is some mistake in the app config file but the connection string was generated by entity framework. So I'm stuck MyDB Structure
Because your localdb is copied to bin folder every time you run it. It gets overwritten everytime you run/debug it. Main file in the project folder is not updated.
For detailed answer:
https://social.msdn.microsoft.com/Forums/en-US/393bddc6-0b85-4c27-9475-27172e50d2d9/entity-framework-doesnt-save-new-record-into-database?forum=adodotnetentityframework

How to use custom configuration file or app.config in .NET application

I have MVC5 .NET 4.6.1 C# web application
I want to create a custom config file separate from web.config to store some settings my application uses.
I tried to follow this article https://support.microsoft.com/en-us/kb/815786
however the items I set in app.config:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.6.1" />
<httpRuntime targetFramework="4.6.1" />
</system.web>
<appSettings>
<add key="Key0" value="0" />
<add key="Key1" value="1" />
<add key="Key2" value="2" />
</appSettings>
</configuration>
are not seen in my application see , eg. they come as null:
string attr = ConfigurationManager.AppSettings["Key0"];
Why isn't it working? Am I missing something?
Alternatively I would like to create a custom config file eg. mycustom.config to define my global app settings.
EDIT
Solution I used
Follwing this post https://social.msdn.microsoft.com/Forums/vstudio/en-US/11e6d326-c32c-46b1-a9a2-1fbef96f33ee/howto-custom-configuration-files?forum=netfxbcl
In web.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="newAppSettings" type="System.Configuration.AppSettingsSection, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</configSections>
<newAppSettings file="C:\mycustom.config"/>
</configuration>
Then mycustom.config
<?xml version="1.0" encoding="utf-8" ?>
<newAppSettings>
<add key="OurKey" value="OurValue"/>
</newAppSettings>
And reading the value:
System.Collections.Specialized.NameValueCollection newAppSettings = (System.Collections.Specialized.NameValueCollection)System.Configuration.ConfigurationManager.GetSection("newAppSettings");
string key = Convert.ToDateTime(newAppSettings["OurKey"]);
You can use separate config file for connection strings and app settings:
<appSettings configSource="appSettings.config" />
<connectionStrings configSource="connectionStrings.config"/>
appSettings.config file
<?xml version="1.0" encoding="utf-8" ?>
<appSettings>
<add key="Setting1" value="App setting 1" />
</appSettings>
connectionStrings.config file
<?xml version="1.0" encoding="utf-8"?>
<connectionStrings>
<add name="MyConnStr1" connectionString="My connection string" />
</connectionStrings>
Usage is same as it was before:
var setting1 = ConfigurationManager.AppSettings["Setting1"];
var connString1 = ConfigurationManager.ConnectionStrings["MyConnStr1"].ConnectionString;
//Helps to open the Root level web.config file.
Configuration webConfigApp = WebConfigurationManager.OpenWebConfiguration("~");
//Modifying the AppKey from AppValue to AppValue1
webConfigApp.AppSettings.Settings["AppKey"].Value = "AppValue1";
<appSettings>
<add key="AppKey" value="AppValue"/>
</appSettings>

Categories

Resources