I am trying to change the connection String values
connectionString="Data Source=localhost;Initial Catalog=Tracker;Persist Security Info=false;User ID=sa;Password=p#ssw0rd"
from my user interface. Could any one help to change the settings from the user interface in the windows application?
From the comment thread on the original post, it sounds like the OP needs to enumerate data sources and allow a user to pick one (and perhaps store that preference). Assuming that is the case...
The actual connection to the database should be secured using integrated Windows security if at all possible. This a best practice. Integrated security eliminates the need to store credentials anywhere.
If the goal is to pick a datasource, it's not hard to list all databases within an environment using C#.
The user's preference/selection should be stored somewhere other than the app.config. The registry, isolated storage, or an XML file are all valid options if no credentials are involved.
ASP.NET provides the Web Site Administration Tool to view and manage the configuration settings for your ASP.NET website. These configuration settings are stored in an xml file called web.config.
web.config is an application configuration file used to define configuration settings such as connecting strings, authentication, authorization etc., for an ASP.NET application
The tool provides an easy to use interface to edit the configuration settings. However this tool works well when you have to manually make changes. At times, there could be a possibility where we need to make changes to the web.config at runtime. For example: a user requesting to control the connecting string, change session timeouts and so on.
For this purpose, ASP.NET provides the Configuration API to programmatically manipulate the configuration settings in web.config. The API’s are contained in the System.Configuration and System.Web.Configuration namespaces. In fact, internally the Web Site Administration Tool uses the same API to edit configuration settings.
The WebConfigurationManager class in the System.Web.Configuration namespace is used to create a Configuration object. This object is used to read and write changes to the web.config file. See.
See also Securing Connection Strings
Let me clarify that this is not what you're asking but by reading this, you will be able to find some clues and come to know what is recommended and what is not.
If this is a Windows application then you don't need to change the app.config file to change the active database connection. I've written about this on my blog.
User below method to change connection string using C# :
public void SaveConnectionString(DbInfo dbinfo, string path,string appConfigFile)
{
try
{
string configFile = Path.Combine(path, appConfigFile);
var doc = new XmlDocument();
doc.Load(configFile);
XmlNodeList endpoints = doc.GetElementsByTagName("connectionStrings");
foreach (XmlNode item in endpoints)
{
if (item.HasChildNodes)
{
foreach (var c in item.ChildNodes)
{
if (((XmlNode)c).NodeType == XmlNodeType.Element)
{
var adressAttribute = ((XmlNode)c).Attributes["name"];
if (adressAttribute.Value.Contains("YourConStrName"))
{
if (dbinfo.dbType == dataBaseType.Embedded)
{
((XmlNode)c).Attributes["connectionString"].Value = SetupConstants.DbEmbededConnectionString;
((XmlNode)c).Attributes["providerName"].Value = SetupConstants.DbEmbededConnectionProvider;
}
else if (dbinfo.dbType == dataBaseType.Microsoft_SQL_Server)
{
if (dbinfo.sqlServerAuthType == SqlServerAuthenticationType.SQL_Server_Authentication)
{
// ((XmlNode)c).Attributes["connectionString"].Value = string.Format(SetupConstants.dbConnStringwithDb, dbinfo.databaseAdress, SetupConstants.SqlDbName, dbinfo.userId, dbinfo.password) + "MultipleActiveResultSets=true;";
((XmlNode)c).Attributes["connectionString"].Value = string.Format(SetupConstants.dbConnStringwithDb, dbinfo.databaseAdress, dbinfo.DatabaseName, dbinfo.userId, dbinfo.password) + "MultipleActiveResultSets=true;";
}
else if (dbinfo.sqlServerAuthType == SqlServerAuthenticationType.Windows_Authentication)
{
//((XmlNode)c).Attributes["connectionString"].Value = string.Format("Data Source={0};Initial Catalog={1};Integrated Security=True;MultipleActiveResultSets=true;", dbinfo.databaseAdress, SetupConstants.SqlDbName);
((XmlNode)c).Attributes["connectionString"].Value = string.Format("Data Source={0};Initial Catalog={1};Integrated Security=True;MultipleActiveResultSets=true;", dbinfo.databaseAdress, dbinfo.DatabaseName);
}
((XmlNode)c).Attributes["providerName"].Value = SetupConstants.DbSqlConnectionProvider;
}
}
}
}
}
}
doc.Save(configFile);
string exePath = Path.Combine(path, "EDC.Service.exe");
InstallerHelper.EncryptConnectionString(true, exePath);
}
catch (Exception ex)
{
//TODO://log here exception
Helper.WriteLog(ex.Message + "\n" + ex.StackTrace);
throw;
}
}
Add bellow class DBinfo
public class DbInfo
{
public DataBaseType dbType { get; set; }
public SqlServerAuthenticationType sqlServerAuthType { get; set; }
public string ConnectionString { get; set; }
public string databaseAdress { get; set; }
public string userId { get; set; }
public string password { get; set; }
public string Port { get; set; }
public string DatabaseName { get; set; }
}
public enum DataBaseType
{
Unknown = 0,
Embedded = 1,
Microsoft_SQL_Server =2,
}
public enum SqlServerAuthenticationType
{
Windows_Authentication = 0 ,
SQL_Server_Authentication =1
}
Related
i need a config file for my applications and i've looked through internet without really finding what I want, I want to set my config to a var and use it like config.somethingInTheConfig.
I tried some things but it didn't work,
the config file :
{
"id": 00,
"somethings": true,
"yes": "idkjustsomething"
}
the Config class :
class Config
{
public static int id { get; set; }
public static bool somethings { get; set; }
public static string yes { get; set; }
}
Code to read it
using (StreamReader streamReader = new StreamReader("config.json"))
{
string json = streamReader.ReadToEnd();
Config config = JsonConvert.DeserializeObject<Config>(json);
Console.WriteLine(config.id);
}
I want it to show the id in the config in the console but it doesn't work nd gives me an error, anyone could help ?
The properties are marked static.
JsonConvert will not be able to read values into the static properties.
And since you are not defining values for them at design time, the properties will be set to their default values unless you manually change them.
I am finding a lot of different ways to do this and I'm not sure the direction I should go...
I have an application that will run on several personal computers. I am looking for a way to keep a list of application settings persistently.
The idea being that the user will be able to choose amongst a list of applications. Those applications will then be saved until the user removes them. I need to save the application name and the corresponding path.
The problem is that I can't seem to save the key, value pairs to new settings in visual studio and have them persist. I need to write a file to save the files, how do I go about doing that... Should I write them to system.configuration, JSON or XML??? Does anyone have a good walkthrough?
Well, there are a lot of ways to do that. For a simple approach, you can use XML serialization. First create a class that represents all the settings you want to save, and add the Serializable attribute to it, for example:
[Serializable]
public class AppSettings
{
public List<UserApp> Applications { get; set; }
}
[Serializable]
public class UserApp
{
public string Path { get; set; }
public string Name { get; set; }
}
Then, add the following methods to it:
public static void Save(AppSettings settings)
{
string xmlText = string.Empty;
var xs = new XmlSerializer(settings.GetType());
using (var xml = new StringWriter())
{
xs.Serialize(xml, settings);
xml.Flush();
xmlText = xml.ToString();
}
string roamingPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
File.WriteAllText(roamingPath + #"\settings.xml", xmlText);
}
public static AppSettings Load()
{
string roamingPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
if (!File.Exists(roamingPath + #"\settings.xml"))
return new AppSettings();
string xmlText = File.ReadAllText(roamingPath + #"\settings.xml");
var xs = new XmlSerializer(typeof(AppSettings));
return (AppSettings)xs.Deserialize(new StringReader(xmlText));
}
Then, to save, do:
AppSettings settings = new AppSettings();
settings.Applications = new List<UserApp>();
settings.Applications.Add(new UserApp { Path = #"C:\bla\foo.exe", Name = "foo" });
AppSettings.Save(settings);
And to load:
AppSettings settings = AppSettings.Load();
You can also edit the loaded settings and save it again, overwriting the older.
For more a more complex approach, save into a database.
Add a setting to the settings using the instructions shown in below screenshot:
NOTE: Double click Properties shown with first arrow.
Then you can update that value at runtime like this:
namespace ConsoleApplication1
{
public class Program
{
public static void Main()
{
var defSettings = ConsoleApplication1.Properties.Settings.Default;
var props = defSettings.Test = "Whatever";
// Save it so it persists between application start-ups
defSettings.Save();
Console.Read();
}
}
}
The settings will be stored in the user's profile.
This question already has answers here:
How can I save application settings in a Windows Forms application?
(14 answers)
Closed 7 years ago.
Question
How can I save "settings" so that they can be used again after the application has been closed?
When I say settings I mean different properties of the controls on my form.
What is the easiest and most appropriate method? I've read you can save to the system registry or a xml file?
Background
I have a form that creates a row in a Table that changes depending on what control is set or change.
I would like to be able to save different configurations and display them in a combobox for repeated use.
Example
The end user fill in all textboxs and ticks checkboxes.
They then click add to favourites
They add a favourite name and save
The save is then permanently visible in the favourites combobox.
My form
There are many ways to do this. But in all these options, you need to store the users selection somewhere. You can store this in
A database table, associate the setting with a unique user ID, like LoginID
A Preferences XML file : Refer this
As a Setting in your project : Refer this
As a Registry Entry : Refer this
An INI File
You might want to take a look at Persisting Application Settings in the .NET Framework
One way you could save the data would be to write it to the registry, under the HKCU node. This way different users of your application will have their own settings even if the app is on the same machine. It also keeps the file system a little cleaner and doesn't require a database. But the downside is that the favorites only live on the machine, and don't roam with the user across devices.
A way to implement this would be to wrap your form settings in a class that knows how to save and load values from the registry. This, along with a registry helper class, could make it pretty easy to add "Favorites" functionality to your form.
For example, you could first create a Registry helper class that will read and write settings to the HKCU node (so the settings are specific to the logged in user):
public class RegHelper
{
private static readonly RegistryKey Root = Registry.CurrentUser
.CreateSubKey(#"Software\CompanyName\ApplicationName");
private readonly RegistryKey _thisKey = Root;
public RegHelper() { }
public RegHelper(string favoriteKey)
{
_thisKey = Root.CreateSubKey(favoriteKey);
}
public List<string> GetSubKeys()
{
return _thisKey.GetSubKeyNames().ToList();
}
public void SetProperty(string propertyName, string value)
{
_thisKey.SetValue(propertyName, value, RegistryValueKind.String);
}
public void SetProperty(string propertyName, bool value)
{
SetProperty(propertyName, value.ToString());
}
public string GetProperty(string propertyName)
{
return GetProperty(propertyName, string.Empty);
}
public string GetProperty(string propertyName, string defaultValue)
{
return _thisKey.GetValue(propertyName, defaultValue).ToString();
}
public bool GetPropertyAsBool(string propertyName)
{
return bool.Parse(GetProperty(propertyName, default(bool).ToString()));
}
}
Then, you could wrap the fields of your form into a class that not only has properties that match your form fields, but also has methods to save the values to the registry and some static methods to load all Favorites or a specific named Favorite. For example:
public class Favorite
{
public string Name { get; private set; }
public string Notes { get; set; }
public bool NotesFromPlanner { get; set; }
public string Project { get; set; }
public string DbLocation { get; set; }
public string AssesmentToolVersion { get; set; }
public string ProjectCodes { get; set; }
public bool StraightToNew { get; set; }
public Favorite(string name)
{
this.Name = name;
}
public void Save()
{
var reg = new RegHelper(this.Name);
reg.SetProperty("Name", Name);
reg.SetProperty("Notes", Notes);
reg.SetProperty("NotesFromPlanner", NotesFromPlanner);
reg.SetProperty("Project", Project);
reg.SetProperty("DbLocation", DbLocation);
reg.SetProperty("AssesmentToolVersion", AssesmentToolVersion);
reg.SetProperty("ProjectCodes", ProjectCodes);
reg.SetProperty("StraightToNew", StraightToNew);
}
public static Favorite GetFavorite(string favoriteName)
{
var reg = new RegHelper(favoriteName);
return new Favorite(favoriteName)
{
Notes = reg.GetProperty("Notes"),
NotesFromPlanner = reg.GetPropertyAsBool("NotesFromPlanner"),
Project = reg.GetProperty("Project"),
DbLocation = reg.GetProperty("DbLocation"),
AssesmentToolVersion = reg.GetProperty("AssesmentToolVersion"),
ProjectCodes = reg.GetProperty("ProjectCodes"),
StraightToNew = reg.GetPropertyAsBool("StraightToNew"),
};
}
public static List<Favorite> GetFavorites()
{
return new RegHelper().GetSubKeys().Select(GetFavorite).ToList();
}
public override string ToString()
{
return this.Name;
}
}
Then, you could use the Favorite class to populate your Favorites drop down:
private void Form1_Load(object sender, EventArgs e)
{
// Get all saved favorites and load them up in the combo box
foreach (var favorite in Favorite.GetFavorites())
{
cboFavorites.Items.Add(favorite);
}
}
Now, when a favorite is picked from the combo box, we want to populate our form with the details:
private void cboFavorites_SelectedIndexChanged(object sender, EventArgs e)
{
var favorite = (Favorite) cboFavorites.SelectedItem;
txtNotes.Text = favorite.Notes;
txtAssetToolVersion.Text = favorite.AssesmentToolVersion;
txtDbLocation.Text = favorite.DbLocation;
chkNotesFromPlanner.Checked = favorite.NotesFromPlanner;
txtProjectCodes.Text = favorite.ProjectCodes;
cboProjects.Text = favorite.Project;
chkStraightToNew.Checked = favorite.StraightToNew;
}
And when someone clicks "Save Favorite", we want to add (or update) the favorite details to the registry:
private void btnAddFavorite_Click(object sender, EventArgs e)
{
string favoriteName = cboFavorites.Text;
if (string.IsNullOrEmpty(favoriteName))
{
MessageBox.Show("Please type a name for the favorite in the Favorites box.");
return;
}
var favorite = new Favorite(favoriteName)
{
Notes = txtNotes.Text,
AssesmentToolVersion = txtAssetToolVersion.Text,
DbLocation = txtDbLocation.Text,
NotesFromPlanner = chkNotesFromPlanner.Checked,
ProjectCodes = txtProjectCodes.Text,
Project = cboProjects.Text,
StraightToNew = chkStraightToNew.Checked
};
favorite.Save();
// When saving a favorite, add it to the combo box
// (remove the old one first if it already existed)
var existingFav = cboFavorites.Items.Cast<Favorite>()
.FirstOrDefault(fav => fav.Name == favoriteName);
if (existingFav != null)
{
cboFavorites.Items.Remove(existingFav);
}
cboFavorites.Items.Add(favorite);
cboFavorites.Text = favoriteName;
}
This should be enough to get you started, if you want to go the registry route.
It depends on your application and what it's used for and its architecture.
There are multiple options:
You could save it in a database.
This option is nice when there are a lot of settings and especially nice in a multi-user platform. If this is a client server application, this may also be preferable for that reason. If you want to keep this simple and don't see user settings getting complex / having very many, this may not be the best option.
You could save it in a flat file. This option is similar to the first, but likely better in the case where your application is more stand-alone and/or you just don't have any other benefit of having those settings on a server.
You could store them in your Applications Settings. There is a good answer regarding how to do that here: https://msdn.microsoft.com/en-us/library/0zszyc6e%28v=vs.110%29.aspx
Another thing to consider is how you want to load those settings. For windows forms development, having classes which define your layout and binding to those classes can be useful. Therefore, you may want to store this data in XML which can be easily serialized directly into a class which defines what your form looks like. You would be able to store that XML anywhere really: Locally or on the server in a database.
Over the last couple of days I've been researching WCF. I've been reading various discussions and following a number of different walkthroughs, most notably the one linked below.
WCF Getting Started Tutorial
I'm now trying to convert these skills into a different scenario. The file structure is exactly the same as what was stated in the aforementioned walkthrough. There is one WCF Service Library, a Host (Console Application) and a Client (Console Application). The host is setup in the same manor as the walkthrough, the client has been altered to allow user input instead of hardcoded values and the WCF code has been provided below.
After a value is provided the WCF Library will run until the following line var userData = repository.GetById(userId);. When the breakpoint is reached and I step over, an exception is thrown stating that the ConnectionString expected doesn't exist. I've tested putting the connection string in the Client and WCF projects but to no avail. I've also ensured EntityFramework and Service.Configuration DLLs are also added as references.
It's possible I am missing another DLL, App.config setting or I've completely messed up and misinterpretted what I can do with a WCF Service Library so I'm looking for some advice on how to rectify the issue in the previous paragraph or a link which helps me understand the problem
IService.cs Code
[ServiceContract(Namespace = "....")]
public interface IUser
{
[OperationContract]
User GetUser(int userId = 0);
}
[DataContract]
public class User
{
[DataMember]
public int UserId { get; set; }
[DataMember]
public string UserName { get; set; }
[DataMember]
public string FirstName { get; set; }
[DataMember]
public string LastName { get; set; }
}
Service.cs Code
public class UserService : IUser
{
public User GetUser(int userId = 0)
{
User user = null;
using (var context = new Context())
{
var repository = new Repository(context);
var userData = repository.GetById(userId);
if (userData != null)
{
user = new User
{
UserId = userId,
FirstName = userData.CustomerFirstName,
LastName = userData.CustomerSurname,
UserName = userData.CustomerEmail
};
Console.WriteLine("UserId : {0}", userId);
Console.WriteLine("FirstName : {0}", userData.CustomerFirstName);
Console.WriteLine("LastName : {0}", userData.CustomerSurname);
Console.WriteLine("UserName : {0}", userData.CustomerEmail);
}
}
return user;
}
}
Edit:
<add name="CONTEXT"
connectionString="Server=SERVER;Database=DATABASE;uid=DATABASE;pwd=DATABASE;"
providerName="System.Data.SqlClient" />
Your connection string must be set in the App.config of the executing assembly, not in the assembly directly using it. This means that although your service implementation (Service.cs) is located in your WCF Library assembly, the connection string must be located in the App.config of your host project. If you declare an App.config file into your WCF Library, it will simply be ignored.
The client will not access the database, it will consume your service which is who accesses the database. Therefore, there is no need to declare the connectiong string in the client App.config.
I want to create a WinForms application.
This application will have many configurable options that will be saved in a database, so they can be persisted across executions (e.g. print settings, design options, etc.).
What approach would you recommend for loading these options, to avoid frequent access to the database?
Thanks!
If it security isn't important, you could also have the settings saved in an xml file that your form reads in. You could have a class that loads the properties that you need.
http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx
[Serializable()]
public class Defaults
{
public string Description { get; set; }
public double Tolerance { get; set; }
public string Units { get; set; }
}
internal class FormDefaults
{
public void LoadSettings()
{
string kfileString = #"C:\Default_Settings.xml";
var q = from el in XElement.Load(kfileString).Elements()
select new FormDefault()
{
Description = el.Element("InstrumentDescription").Value,
Tolerance = Double.Parse(el.Element("InstrumentMassTolerance").Value),
Units = el.Element("InstrumentMassUnits").Value,
};
}
}
}
That's pretty rough but I had something similar that worked pretty well and was pretty easy to set up.
Cheers
There are some problems, the settings saved in the database will be shared by all the users. In this case you have think about having settings for each user. Better option would be saving in the local config file which can be encrypted and used. If anything needs to shared across users then can use db for that particular option. You can load those option before application loads and access it through objects.
You can do these database fetch operations in the SPlash screen by showing progress to the users.