Save data in a Visual Studio WPF aplication without a database - c#

I'm developing a WPF app using C#.
The first thing my app does is trying to connect to the database, so I ask for some data to connect to the database like the name of the server (could be the IP too), the name of the database, the name of MySQL instance user and password, and the port (3306 for default). But I want to save this info in the app because I don't have the database yet to save there.
I want to save this strings in the application without using a database:
Computer Name
Name of the database backup
MySql Instance User
MySql Instance Pass
Port
I don't want to save this data in the database because I need this info for the first use of the application.
With first use I mean before the database backup is even restored to the server from the installer.

You can save file with registry. Try this :
Microsoft.Win32.RegistryKey RegistryKey = Microsoft.Win32.Registry.CurrentUser.CreateSubKey("WPF APPLICATION");
RegistryKey.SetValue(SET THE VALUE);
RegistryKey.Close();

best practice is to store these values in configuration file. like a .ini file or xml file.
if your data is sensitive and you don't wish to see this details directly you can encrypt this data with any convenient encryption method.
so your ini file structure will look like this,
[port]=3306
[ip]=111.222.1.2
hope this will help.

Try using the app.Config.
The main benefit of the app.config is that It's directly attached to your executable. Once you build your solution, the app.config gets copied together with the executable.
From What is App.config in C#.NET? How to use it?:
At its simplest, the app.config is an XML file with many predefined configuration sections available and support for custom configuration sections. A "configuration section" is a snippet of XML with a schema meant to store some type of information.
Settings can be configured using built-in configuration sections such as connectionStrings or appSettings. You can add your own custom configuration sections; this is an advanced topic, but very powerful for building strongly-typed configuration files.
Source for app.config in msdn: How to: Add an Application Configuration File to a C# Project

.NET Applications are compiled with a .config file like "YourApp.exe.config" next to the .exe.
This file should be used for such purposes, and can be accessed in code with the ConfigurationManager.

/You can Save Data in XML file/
//You can Save and load time by this method but it's slow process,
it may crash if data is large and system is slow, it stores data runtime
so takes RAM, its ok to use for few rows without any problem
//use the collection for storing data runtime
List<Person> pers = new List<Person>();
public class Person
{
public string id { get; set; }//1
public string name { get; set; }//2
public string bilno { get; set; }//3
public string mob { get; set; }//4
public DateTime dt { get; set; }//5
}
string path=#"c:\.....";
void save()
{
XmlDocument xdoc = new XmlDocument();
xdoc.Load(path + #"\data.xml");
XmlNode xnode = xdoc.SelectSingleNode("Items");
xnode.RemoveAll();
foreach (Person i in pers)
{
XmlNode xtop = xdoc.CreateElement("Item");
XmlNode x1 = xdoc.CreateElement("a");
XmlNode x2 = xdoc.CreateElement("b");
XmlNode x3 = xdoc.CreateElement("c");
XmlNode x4 = xdoc.CreateElement("d");
XmlNode x5 = xdoc.CreateElement("e");
x1.InnerText = i.id;
x2.InnerText = i.name;
x3.InnerText = i.bilno;
x4.InnerText = i.mob;
x5.InnerText = i.dt.ToFileTime().ToString();
xtop.AppendChild(x1);
xtop.AppendChild(x2);
xtop.AppendChild(x3);
xtop.AppendChild(x4);
xtop.AppendChild(x5);
xdoc.DocumentElement.AppendChild(xtop);
}
xdoc.Save(path + #"\data.xml");
}
void load()
{
XmlDocument xdoc = new XmlDocument();
xdoc.Load(path + #"\data.xml");
foreach (XmlNode xnode in xdoc.SelectNodes("Items/Item"))
{
Person p = new Person();
p.id = xnode.SelectSingleNode("a").InnerText;
p.name = xnode.SelectSingleNode("b").InnerText;
p.bilno = xnode.SelectSingleNode("c").InnerText;
p.mob = xnode.SelectSingleNode("d").InnerText;
p.dt = DateTime.FromFileTime(Convert.ToInt64(xnode.SelectSingleNode("e").InnerText));
}
}

Related

How to add a field in my quartz configuration dynamically?

I have a quartz configuration section in my web.config, and I want to add a key value field to it. (I know I can just go to the web.config and add it manually but that defeats the purpose)
I tried using this way
var config = (NameValueCollection)WebConfigurationManager.GetSection("quartz");
config.Add("quartz.dataSource.quartzDS.connectionString", "data source =..");
but it failed because collection is read only and can't be modified. Any tip to how to do this?
Edit: I ended up copying the config to a nameValueCollection and then copying it to another one (for the readonly properties) add the key values I want and passing it to the function I needed.
var oldConfig = (NameValueCollection)WebConfigurationManager.GetSection("quartz");
var config = Test(oldConfig);
var connectionString = unitOfWork.GetConnectionStringByTenantIdentifier(tenantId);
config.Add("quartz.dataSource.quartzDS.connectionString", connectionString);
await unitOfWork.GetService<SchedulerService>().StartScheduler(config, tenantId);
this way I will have the custom configuration for every tenant the way I want it. Sorry if my question wasn't clear.
You can actually do this in two ways.
One way is to set your dynamic connection string in the standard AppSettings section and then create a new Quartz Scheduler with a new set of XML properties (an example is provided in Quartz.NET distribution, so I will cut this short)
var properties = new NameValueCollection
{
["quartz.scheduler.instanceName"] = "XmlConfiguredInstance",
["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz",
... etc.
};
ISchedulerFactory sf = new StdSchedulerFactory(properties);
IScheduler sched = await sf.GetScheduler();
Then you can save your non-const string in the AppSettings and get it form there.
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.AppSettings.Settings.Add("quartz.dataSource.quartzDS.connectionString", connstring);
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
Or you can read your whole settings file as XML, as previously answered, BUT you have to make sure that any edits are done before you initialize the default Quartz Scheduler, as it's properties become read-only, and to change them you will have to create a new ISchedulerFactory anyway, which kinda beats the purpose.
var xmlDoc = new XmlDocument();
xmlDoc.Load(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
xmlDoc.SelectSingleNode("//quartz/add[#key='quartz.dataSource.quartzDS.connectionString']").Attributes["value"].Value = "...";
xmlDoc.Save(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
ConfigurationManager.RefreshSection("quartz");
But I advise you not to edit your main config file at runtime at all, and instead use an ISchedulerFactory XmlConfiguredInstance while getting and saving the connstring into a UAC-compatible location in any format you like (to prevent Modifying app.config at runtime throws exception from happening)
Still if you want to use the config file you can use this tutorial from Yi Zeng for further reading
You can try using XmlDocument classes to go to a lower level.
Make sure the user of your app has write permissions to the config file
public static void WriteKey(String configFileName, String key, String value)
{
XmlDocument doc = new XmlDocument();
doc.Load(configFileName);
XmlNode node = doc.SelectSingleNode("//quartz");
if (node == null)
{
throw new InvalidOperationException("quartz section not found in config file.");
}
try
{
XmlElement elem = (XmlElement)node.SelectSingleNode(string.Format("//add[#key='{0}']", key));
if ((elem != null))
{
elem.SetAttribute("value", value);
}
else
{
elem = doc.CreateElement("add");
elem.SetAttribute("key", key);
elem.SetAttribute("value", value);
node.AppendChild(elem);
}
doc.Save(configFileName);
}
catch
{
throw new InvalidOperationException("Error writing config file");
}
}

Issue with Xml Project

I'm looking for some help.
I created an mp3 web service using visual studio c# and xml to store the data. I created a method that will allow a user to create a new playlist id to be stored to the xml document. I set my xml file as follows:
public class Service : System.Web.Services.WebService
{
//used as an access path to the xml file
string xmlFileName = "F:\\WebServices\\Mp3Server\\SongList.xml";
This is before any of the methods in my program.
My songlist.xml file is stored correctly and is the correct path from what I can see.
I currently had mp3 id's stored on the songlist.xml file is as follows:
<Playlist ID="123">
<Song Title="Bump">
<Artist>Ed Sheeran</Artist>
<Album>Asylum</Album>
<Year>2011</Year>
<Genre>Folk</Genre>
</Song>
<Song Title="3 AM">
<Artist>Matchbox Twenty</Artist>
<Album>Exile On Mainstream</Album>
<Year>2007</Year>
<Genre>Rock</Genre>
</Song>
</Playlist>
The code I wrote to create a new playlist id is as follows:
//creates a new playlist
[WebMethod]
public string createPlaylistName(string playlistID)
{
string errorMessage = "";
List<string> playlistNames = createPlaylist("/SongList//Playlist/ID");
if (playlistNames.Contains(playlistID))
{
errorMessage = "error! Id already exists";
}
else
{
string xpath = "/SongList/Playlist[#ID'" + playlistID + "']";
XmlDocument doc = new XmlDocument();
doc.Load(xmlFileName);
XmlElement root = doc.DocumentElement;
XmlNode playistNode = root.SelectSingleNode(xpath);
XmlElement playList = doc.CreateElement("Playlist");
XmlAttribute ID = doc.CreateAttribute("ID");
ID.Value = playlistID;
playList.Attributes.Append(ID);
playistNode.InsertAfter(playList, playistNode.LastChild);
doc.Save(xmlFileName);
errorMessage = "success";
}
return errorMessage;
}
But when I run the program, create a new playlist Id and invoke the command: it displays "page not found" webpage.
I can't figure out why the create method is crashing.
If anyone can give any advice, I would appreciate it very much.
Have you tried stepping through it? You'll find that it fails because your XPath expression isn't valid. Your concatenation creates an expression like this:
/SongList/Playlist[#ID'123']
Where it should be:
/SongList/Playlist[#ID='123']
I'm also not entirely sure the logic makes sense. You're checking that a playlist doesn't exist with that ID and then adding one. So how is your XPath expression supposed to return an element?
As an aside, you should probably look into LINQ to XML - it's a much nicer API, for example:
var doc = XDocument.Load(xmlFileName);
var playlist = doc.Descendants("Playlist")
.Single(e => (string)e.Attribute("ID") == "123");
playlist.AddAfterSelf(
new XElement("Playlist",
new XAttribute("ID", "456")
));

IIS Application : How to get an unique ID

I have an application that manage IIS Application instances so I am looking for a kind of GIUD to identify each applications. This GUID must be created when the application is deployed in IIS and must be persistent to IIS/Windows updates/restarts.
I did not need the use of Microsoft.Web.Administration: I want a simple way, for each IIS application, it returns its unique ID (by a method called within it).
Here is an example of what I'm looking for and I'd like to have an unique id returned by this.????? :
public class MvcApplication : System.Web.HttpApplication
{
string myUniqueID {
get { return this.?????; }
}
}
Thanks for help.
HostingEnvironment.ApplicationID
https://msdn.microsoft.com/en-us/library/system.web.hosting.hostingenvironment.applicationid(v=vs.110).aspx
I had to do something similar.
Read the web.config file for a HostId setting. Preferably split your configuration file into two, with one config file that is local to the install, and doesn't get replaced upon upgrading to a new version of the website.
If the HostId value doesn't exist in the web.config, call Guid.NewGuid() to generate a new value.
Save the new value to the web config, preferably in the local section/file.
Return the value.
Here is some psuedo-code:
public Guid HostId
{
get
{
var result = GetSetting(ConfigFileLocalSettingList.HostId).TryToGuid();
if (result == null)
{
result = Guid.NewGuid();
SetSetting(ConfigFileLocalSettingList.HostId, result.ToString());
Save();
}
return result.Value;
}
}
You can use the assembly GUID for this purpose: In AssemblyInfo.cs, you can find
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("307E39B9-2C41-40CF-B29F-84C8BBCD6519")]
To read this value, you can use:
public static string AssemblyGUID
{
get {
var assembly = Assembly.GetExecutingAssembly();
var attribute = (System.Runtime.InteropServices.GuidAttribute)assembly.GetCustomAttributes(typeof(System.Runtime.InteropServices.GuidAttribute), true)[0];
var GUID = attribute.Value;
return GUID;
}
}
which is taken from another SO answer (you can find it here).
And if it is required, Visual Studio allows you to create a new GUID via menu Tools -> Create GUID - if you need a different one.
Or in C# you simply use
var newGuid=(Guid.NewGuid()).ToString();
Console.WriteLine(newGuid);
to create a new GUID.

Read XML files in deployed app to Windows Store

I have a simple service which let me read XML file.
public class SetService : ISetService
{
private const string FilesPath = "Data/Sets.xml";
private string xmlPath = Path.Combine(Package.Current.InstalledLocation.Path, FilesPath);
public async Task<IList<Set>> GetAll()
{
XDocument loadedData = XDocument.Load(xmlPath);
var data = from query in loadedData.Descendants("set")
select new Set
{
Id = (int)query.Element("id"),
Name = (string)query.Element("name"),
IsActive = (bool)query.Element("isactive"),
IsPassed = (bool)query.Element("ispassed"),
};
return (IList<Set>)data.ToList();
}
}
Everything works fine when I am using this method, on my local machine or on emulator provided with Microsoft Visual Studio 2013 but after I published this app to the Windows Store I am not able to see these data from XML files.
What am I doing wrong?

How to use the read/writeable local XML settings?

I found something similar to what I need here:
http://www.codeproject.com/KB/cs/PropertiesSettings.aspx
But it does not quite do it for me. The user settings are stored in some far away location such as C:\documents and settings\[username]\local settings\application data\[your application], but I do not have access to these folders and I cannot copy the settings file from one computer to another, or to delete the file altogether. Also, it would be super-convenient to have the settings xml file right next to the app, and to copy/ship both. This is used for demo-ware (which is a legitimate type of coding task) and will be used by non-technical people in the field. I need to make this quickly, so I need to reuse some existing library and not write my own. I need to make it easy to use and be portable. The last thing I want is to get a call at midnight that says that settings do not persist when edited through the settings dialog that I will have built.
So, user settings are stored god knows where, and application settings are read-only (no go). Is there anything else that I can do? I think app.config file has multiple purposes and I think I once saw it being used the way I want, I just cannot find the link.
Let me know if something is not clear.
You could create a class that holds your settings and then XML-serialize it:
public class Settings
{
public string Setting1 { get; set; }
public int Setting2 { get; set; }
}
static void SaveSettings(Settings settings)
{
var serializer = new XmlSerializer(typeof(Settings));
using (var stream = File.OpenWrite(SettingsFilePath))
{
serializer.Serialize(stream, settings);
}
}
static Settings LoadSettings()
{
if (!File.Exists(SettingsFilePath))
return new Settings();
var serializer = new XmlSerializer(typeof(Settings));
using (var stream = File.OpenRead(SettingsFilePath))
{
return (Settings)serializer.Deserialize(stream);
}
}

Categories

Resources