How can i update app.config connectionstring Datasource value in C#? - winforms

Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.ConnectionStrings.ConnectionStrings["MyConnectionString",String.Format("DataSource={0};")].ConnectionString=textBox1.Text;
config.Save(ConfigurationSaveMode.Modified, true);
ConfigurationManager.RefreshSection("connectionStrings");
I'm having trouble at line two. I cant seem to get the syntax correct. As you can see, i only want to update the DataSource value only. For example, if current value is Data Source=PC001\SQL2008EXPRESS, i want it to be updated to what the client enters in textBox1.
EDIT: Example ConnectionString
<add name="ERPDatabaseTables" connectionString="metadata=res://*/ERPTables.csdl|res://*/ERPTables.ssdl|res://*/ERPTables.msl;provider=System.Data.SqlClient;provider connection string="Data Source=PC001\SQL2008EXPRESS;Initial Catalog=MyDatabase.mdf;Integrated Security=True;MultipleActiveResultSets=True"" providerName="System.Data.EntityClient"/>
so want to update Data Source=PC001\SQL2008EXPRESS portion only

What you actually want is:
Configuration config =
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
// Because it's an EF connection string it's not a normal connection string
// so we pull it into the EntityConnectionStringBuilder instead
EntityConnectionStringBuilder efb =
new EntityConnectionStringBuilder(
config.ConnectionStrings.ConnectionStrings["ERPDatabaseTables"]
.ConnectionString);
// Then we extract the actual underlying provider connection string
SqlConnectionStringBuilder sqb =
new SqlConnectionStringBuilder(efb.ProviderConnectionString);
// Now we can set the datasource
sqb.DataSource = textBox1.Text;
// Pop it back into the EntityConnectionStringBuilder
efb.ProviderConnectionString = sqb.ConnectionString;
// And update...
config.ConnectionStrings.ConnectionStrings["ERPDatabaseTables"]
.ConnectionString = efb.ConnectionString;
config.Save(ConfigurationSaveMode.Modified, true);
ConfigurationManager.RefreshSection("connectionStrings");
This presumes:
Your EF connection string exists in the app's config file
You have a reference to System.Data.Entity

Related

Change the connection string of nopCommerce?

I am using nopCommerce and I need to remove the connection string in the settings.txt file and insert the web.config file. How can i do this?
The most straightforward way to move the connection string out of settings.txt and into the web.config is to modify the Nop.Core.Data.DataSettingsManager. Specifically the LoadSettings() and SaveSettings() methods. You can store the connection string wherever you'd like (ideally in web.config), as long as those two methods read and write the configuration.
A rough example of the DataSettingsManager updated to support storing the connection string in web.config can be found in this Gist: http://git.io/vUPcI Just copy the connection string from settings.txt to web.config and name the connection "DefaultConnection" or adapt the code accordingly.
Just do two steps
Replace two method LoadSettings and SaveSettings in \nopCommerce\Libraries\Nop.Core\Data\DataSettingsManager.cs. Code from link of #Stephen Kiningham
/// <summary>
/// Load settings
/// </summary>
/// <param name="filePath">File path; pass null to use default settings file path</param>
/// <returns></returns>
public virtual DataSettings LoadSettings(string filePath = null)
{
try
{
System.Configuration.Configuration webConfig = WebConfigurationManager.OpenWebConfiguration(HttpRuntime.AppDomainAppVirtualPath);
return new DataSettings
{
DataConnectionString = webConfig.ConnectionStrings.ConnectionStrings["DefaultConnection"].ConnectionString,
DataProvider = webConfig.ConnectionStrings.ConnectionStrings["DefaultConnection"].ProviderName
};
}
catch (NullReferenceException)
{
return new DataSettings();
}
}
/// <summary>
/// Save settings to a file
/// </summary>
/// <param name="settings"></param>
public virtual void SaveSettings(DataSettings settings)
{
if (null == settings) throw new ArgumentNullException("settings");
System.Configuration.Configuration webConfig = WebConfigurationManager.OpenWebConfiguration(HttpRuntime.AppDomainAppVirtualPath);
webConfig.ConnectionStrings.ConnectionStrings["DefaultConnection"].ConnectionString = settings.DataConnectionString;
webConfig.ConnectionStrings.ConnectionStrings["DefaultConnection"].ProviderName = settings.DataProvider;
webConfig.Save();
}
Add connection string to your web config web.config
<connectionStrings>
<add name="DefaultConnection"
connectionString=" Data Source=localhost;Initial Catalog=nopcommerce;Integrated Security=True;Persist Security Info=False"
providerName="sqlserver">
</add>
</connectionStrings>
[1] In .NET Core (3.1 | NopCommerce 4.3) I created various appsettings.json files (including appsettings.json, appsettings.Development.json, appsettings.Integration.json, appsettings.Staging.json) and logic (beyond this discuss) determines the the correct settings to be used in the proper environment etc.
[2] \nopCommerce\Libraries\Nop.Core\Data\DataSettingsManager.cs
I created the following method:
public static string GetConnectionString()
{
var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
string appSettingsFileName = env switch
{
"Development" => "appsettings.Development.json",
"Production" => "appsettings.json",
"Staging" => "appsettings.Staging.json",
"Integration" => "appsettings.Integration.json",
_ => "appsettings.json",
};
IConfigurationRoot configuration = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile(appSettingsFileName).Build();
string connectionString = configuration.GetConnectionString("DefaultConnection");
return connectionString;
}
(returns the proper connection string for the proper environment)
[3] In LoadSettings -- I didn't change anything to get down to the line
Singleton<DataSettings>.Instance = JsonConvert.DeserializeObject<DataSettings>(text);
... I just added a new line below to replace the .ConnectionString with the connectionstring determined from our new method:
Singleton<DataSettings>.Instance.ConnectionString = GetConnectionString();
important:
When I ran it there were three or four places where there was a switch (case > default:) that was looking for a provider etc -- But I just copied the settings from MsSql down to the default: and it worked fine. I know this is sloppy but I am never using MySql for this project and so far as I am concerned its a non-issue. Either way - I broke it to make it work (multiple Azure App environments are more important).
I suggest they should have built it the regular way and just provided us with a SQL script for deployment (over engineered a non-issue?) since we usually have to do that anyway for custom development (seems silly to me to hard code a data settings file in App_Data) - but I trust their logic.
Please add this to your web.config under Nop.Web project :
<connectionStrings>
<add name="MyConnectionString"
connectionString="Data Source=serverName;Initial Catalog=DBName;Persist Security Info=False;UserID=userName;Password=password"
</connectionStrings>
Best Regards.
In addition to adding the connection to the web.config, you have to specify the providerName="sqlserver".
Ex) ;Initial Catalog=;Integrated
Security=False;User ID=;Password=;Connect
Timeout=30;Encrypt=True"
providerName="sqlserver" />
This is because the EfDataProviderManager in Nop.Data has a check for the provider name, and will throw an exception if you put the normal
providerName="System.Data.SqlClient"

dyanamically change the database name in SqlMapConfig.xml file

I want to change the database name in SqlMapConfig.xml file from the application, does any one help me?
You can override the database when you instantiate the Ibatis mapper instance; I do this for switching between debug and release builds of the application and hence accessing a different target database.
If your xml file is in an assembly called DatalayerAssembly for example, you might have a method for returning your new Ibatis instance based on a database name like this:
public IBatisNet.DataMapper.ISqlMapper CreateNewIbatis(
String serverName,
String databaseName)
{
// Load the config file (embedded resource in assembly).
System.Xml.XmlDocument xmlDoc = IBatisNet.Common.Utilities.Resources.GetEmbeddedResourceAsXmlDocument("SqlMapConfig.xml, DatalayerAssembly");
// Overwrite the connectionString in the XmlDocument, hence changing database.
// NB if your connection string needs extra parameters,
// such as `Integrated Security=SSPI;` for user authentication,
// then append that to InnerText too.
xmlDoc["sqlMapConfig"]["database"]["dataSource"]
.Attributes["connectionString"]
.InnerText = "Server=" + serverName + ";Database=" + databaseName;
// Instantiate Ibatis mapper using the XmlDocument via a Builder,
// instead of Ibatis using the config file.
IBatisNet.DataMapper.Configuration.DomSqlMapBuilder builder = new IBatisNet.DataMapper.Configuration.DomSqlMapBuilder();
IBatisNet.DataMapper.ISqlMapper ibatisInstance = builder.Configure(xmlDoc);
// Now use the ISqlMapper instance ("ibatisInstance") as normal.
return ibatisInstance;
}
I'm using this approach in Ibatis 1.6.2.0 on .Net but the exact SqlMap config file might vary depending by version. Either way the approach is the same; you just might need a different Xml path (i.e. the bit that reads ["sqlMapConfig"]["database"] etc may need changing for your config file)
Hope that helps.

Change Connection String in App.config at runtime

The code below serves to change connection string in App.config at runtime, I found it here but this code did not work for me on Visual Studio 2010 and SQL Server 2008, I could not open the connection to the Northwind database.
using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Text;
using System.Windows.Forms;
using System.Xml;
namespace MyNameSpace
{
public partial class FrmConnectionTest : Form
{
public FrmConnectionTest()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
//Constructing connection string from the inputs
StringBuilder Con = new StringBuilder("Data Source=");
Con.Append(TxtServer.Text);
Con.Append(";Initial Catalog=");
Con.Append(TxtDatabase.Text);
Con.Append(";Integrated Security=SSPI;");
string strCon = Con.ToString();
updateConfigFile(strCon);
//Create new sql connection
SqlConnection Db = new SqlConnection();
//to refresh connection string each time else it will use previous connection string
ConfigurationManager.RefreshSection("connectionStrings");
Db.ConnectionString = ConfigurationManager.ConnectionStrings["con"].ToString();
//To check new connection string is working or not
SqlDataAdapter da = new SqlDataAdapter("select * from employee");
DataTable dt = new DataTable();
da.Fill(dt);
CmbTestValue.DataSource = dt;
CmbTestValue.DisplayMember = "EmployeeID";
}
catch (Exception E)
{
MessageBox.Show(ConfigurationManager.ConnectionStrings["con"].ToString() + ".This is invalid connection", "Incorrect server/Database");
}
}
public void updateConfigFile(string con)
{
//updating config file
XmlDocument XmlDoc = new XmlDocument();
//Loading the Config file
XmlDoc.Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
foreach (XmlElement xElement in XmlDoc.DocumentElement)
{
if (xElement.Name == "connectionStrings")
{
//setting the coonection string
xElement.FirstChild.Attributes[2].Value = con;
}
}
//writing the connection string in config file
XmlDoc.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
}
}
}
Using Visual Studio 2010 and SQL Server2008, I got 2 errors for the next line:
SqlDataAdapter da = new SqlDataAdapter("select * from employee");
Error 1 The best overloaded method match for 'System.Data.SqlClient.SqlDataAdapter.SqlDataAdapter(System.Data.SqlClient.SqlCommand)' has some invalid arguments
Error 2 Argument 1: cannot convert from 'string' to 'System.Data.SqlClient.SqlCommand'
Is there any solution to this issue? Thank you.
The error is telling you that you are passing incorrect parameters to your SqlDataAdapter. I think the proper call would be:
SqlDataAdapter da = new SqlDataAdapter("select * from employee", Db);
Edit
It looks like you're creating your connection string from within your program, saving it to your config file, then reading it out of our config file right before you create your SqlDataAdapter. So, when you debug this line:
Db.ConnectionString = ConfigurationManager.ConnectionStrings["con"].ToString();
Double check that Db.ConnectionString actually contains a connection string.
The other thing to do is open up your SQL Server Management Studio and confirm you can connect to the Northwind database from there. Including/alternatively, in Visual Studio, open your "Server Explorer" window and confirm you can create a Data Connection to Northwind by clicking Add Connection and then setting the connection property window to your server and dropping down the combobox to see if it populates with your databases:
Take a look at the available constructors of the SqlDataAdapter class.
There is no constructor overload that accepts just an SQL String.
You need to use one of the other overloads.
For example, there is one that needs an SQL String and a SqlConnection object.
To use it, change your code like this:
SqlDataAdapter da = new SqlDataAdapter("select * from employee", Db);
EDIT:
As BradRem already mentioned in his comment, try a different connection string.
If his example doesn't work for you, you can find more possible examples at http://connectionstrings.com/sql-server-2008.
Do you really have a database called Northwind on your server?
Does the Windows user on your current machine have permissions on the server to access the database? (that's what Integrated Security=SSPI means - your current Windows user is used to access the database!)

Runtime dynamic SQL Server database access by different connection strings

I've searched the stackoverflow for a long time and didn't find a solution fit my situation, so I asked here.
I have a single asp.net website, and need the web app to access different SQL Server database by the subdomain name.
According to the url request subdomian to determine the access the different database.
prj1.test.com prj1--->use the prj1_DB
prj2.test.com prj2 use the prj2_DB
I couldn't find a better practice to solve the issue.
My intuition solution:
when the url request coming, get the url subdomain, get the subdomain's db connection string stored in the main db, passing the connection string to the DAL to get the data.
Index.aspx.cs
DataTable dt = ProjectObject.GetProjectIndexNotice(new object[] { 0, CurrentProject.DbConnectionString });
ProjectObject.cs
public static DataTable GetProjectIndexNotice(object[] param)
{
ProjectDLC obj = new ProjectDLC();
return obj.GetProjectIndexNotice(param);
}
ProjectDAL.cs
public DataTable GetProjectIndexNotice(object[] param)
{
return base.GetDataTableFromDatabase(param, "NEMP_GetProjectIndexNotice");
}
DALBase.cs
DataBase db = new Microsoft.Practices.EnterpriseLibrary.Data.Sql.SqlDatabase(CurrentProject.DbConnectionString);
I want to find a better way to solve this problem.
The solution I using above is:
get the dbConnectionString from main DB,
passing it over the Index.page ->BusinessObject Layer -->DAL Layer
It's so bad that passing the DB connection string from UI page to the DAL layer.
Any ideas?
Update 1:
What I really want is: don't pass the db connection string from UI to DAL layer.
I want to find a solution that don't do pass the db connstr from UI to DAL linearly.
Is there some pattern in asp.net to share some variable for UI layer and DAL Layer?
Update 2:
if I stored the project db info in a xml file or in the main db, it looks like this
it's a key-value part for the project. here is the question, I get the values all in the main DB or a xml file. How I get the key when I need to access the DB in DAL layer?
in the DAL layer, how to get the correct key for the currnet url request?
it's back to the above, pass the key from UI to DAL. that's I want to avoid.
the real problem is, I can get the key from url request in the UI layer, and I can get the value for that key in the DAL layer. but there is a gap between the two layers, How to conquer this gap?
If you can compute your connection string from a base connection string, then you could do something like this:
store the base connection string in your web.config
<connectionStrings>
<add name="BaseConnString"
connectionString="server=MyServer;database=master;Integrated Security=SSPI;" />
</connectionStrings>
load the base connection string into a SqlConnectionStringBuilder in your code:
string baseConnStr = WebConfigurationManager.ConnectionString["BaseConnString"].ConnectionString;
SqlConnectionStringBuilder scsBuilder =
new SqlConnectionStringBuilder(baseConnStr);
now, just define the database you want to connect to, e.g. based on something in your URL
scsBuilder.InitialCatalog = "ProjectDatabase" + ........ ;
use the resulting complete connection string for your SqlConnection:
using(SqlConnection _con = new SqlConnection(scsBuilder.ConnectionString))
{
// do something
}
Check out the MSDN docs on SqlConnectionStringBuilder.
With this approach, you'd store a single "base" connection string in your web.config and this wouldn't be changing, and using SqlConnectionStringBuilder, you can safely and efficiently define and "compute" your real, "dynamic" connection strings at runtime.
How about adding add the connection strings in web.config as:
Subdomain_connectionString
Now read the subdomain from Request:
Reading connection string from web.config in your DL:
ConfigurationManager.ConnectionStrings[Subdomain_connectionString].ConnectionString
Update:
You can also use xml files to store connection string values:
<ROOT>
<Project_1>
<IPAddress></IPAddress>
<DBName></DBName>
...
</Project_1>
<Project_2>
....
</ROOT>
Anytime a new project is added/removed this xml file would be updated. Use XPath expressions to parse the xml file.
#Passing Connection string from UI to DAL: Just try to add the System.web namespace to DAL layer. This would give access to Request object in DAL. Now you can get the subdomain and build the connectionstring in DAL itself. Not sure whether this is a right approach, but might work in your case.

Can we connect Sharepoint to SQL Server 6.5?

Not able to import application definition file!! Error: The metadata object with Name 'XYZ' and of Type 'LobSystemInstance' has a Property with Name 'DatabaseAccessProvider' that has either an invalid value or Type. Error was encountered at or just before Line: '10' and Position: '10'.
line 10 in ADF:
<"Property Name="DatabaseAccessProvider" Type="System.String">SqlOledb<"/Property>
Please give me ideas on how to display data from SQL Server 6.5 in Sharepoint?
The value of the node is invalid. You need to use SqlServer or OleDb. Check out this page for more information:
http://msdn.microsoft.com/en-us/library/ms550725(office.12).aspx
Im just starting on a similar task (so I found your unanswered question). I am trying to copy our documentation library in Sharepoint to an SQL db. Its not opening your file directly from SQL its using some c# code to setup a job which opens the sharepoint which may be what you are wanting.
There are two methods I have found so far:
One is to copy your data from sharepoint to a linked list in Access and then use the OLEDB methods in to open it.
Found here: C# Sync MS Access database to sql server
private static void BulkCopyAccessToSQLServer
(CommandType commandType, string sql, string destinationTable)
{
string connectionString = #"C:\Migration\Sharepoint Access SQL Batch Job\Database11.accdb";
using (DataTable dt = new DataTable())
{
string ConnStr = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Migration\Sharepoint Access SQL Batch Job\Database11.accdb;Jet OLEDB:Database Password=password";
//using (OleDbConnection conn = new OleDbConnection(Settings.Default.CurriculumConnectionString))
using (OleDbConnection conn = new OleDbConnection(ConnStr))
using (OleDbCommand cmd = new OleDbCommand(sql, conn))
using (OleDbDataAdapter adapter = new OleDbDataAdapter(cmd))
{
cmd.CommandType = commandType;
cmd.Connection.Open();
adapter.SelectCommand.CommandTimeout = 240;
adapter.Fill(dt);
adapter.Dispose();
}
using (SqlConnection conn2 = new SqlConnection(Settings.Default.qlsdat_extensionsConnectionString))
using (SqlConnection conn2 = new SqlConnection(connectionString))
{
conn2.Open();
using (SqlBulkCopy copy = new SqlBulkCopy(conn2))
{
copy.DestinationTableName = destinationTable;
copy.BatchSize = 1000;
copy.BulkCopyTimeout = 240;
copy.WriteToServer(dt);
copy.NotifyAfter = 1000;
}
}
}
}
The other is to use the Microsoft.Sharepoint libraries and open your sharepoint directly from the c# then copy it into your SQL.
Found here: http://www.dotnetspark.com/kb/3573-fetching-lists-from-sharepoint-2010-site.aspx
using (SharePointclientObj.ClientContext ctx = new SharePointclientObj.ClientContext(clientContext))
{
//Get the site
SharePointclientObj.Web site = ctx.Web;
ctx.Load(site);
//Get Lists
ctx.Load(site.Lists);
//Query
ctx.ExecuteQuery();
//Fill List
foreach (SharePointclientObj.List list in site.Lists)
{
Console.WriteLine(list.Title);
}
}

Resources