Windows Form XML Serialization Save Dialog - c#

im stuck with this stupid form... heres my code. It saves it where the streamwriter wants it to but when i save it where the user wants via the savedialog box is creates the XML but doesnt put anything in it! Can someone have a look as it's starting to wind me up!
void SavebuttonClick(object sender, EventArgs e)
{
Stream myStream ;
SaveFileDialog savefile1 = new SaveFileDialog();
savefile1.Filter = "xml files |*.xml" ;
savefile1.FilterIndex = 2 ;
savefile1.RestoreDirectory = true ;
if(savefile1.ShowDialog() == DialogResult.OK)
{
if((myStream = savefile1.OpenFile()) != null)
{
Values v = new Values();
v.task1_name = this.task1_name.Text;
v.task1_desc = this.task1_desc.Text;
v.task1_date = this.task1_date.Value;
v.task1_time = this.task1_time.Value;
SaveValues(v);
}
myStream.Close();
}
}
This is the streamwriter...
public void SaveValues(Values v)
{
XmlSerializer serializer = new XmlSerializer(typeof(Values));
using(TextWriter textWriter = new StreamWriter(#"E:\TheFileYouWantToStore.xml"))
{
serializer.Serialize(textWriter, v);
}
...
}
EDIT:
public class Values
{
public string task1_name { get; set;}
public string task1_desc { get; set;}
public DateTime task1_date { get; set;}
public DateTime task1_time { get; set;}
}
I presume this is the code you meant, im fairly new to coding though mate :(

You must call textWriter.close(); after serialize. If you don't close writer it won't apply chenges to file.
By the way you are writing values to E:\TheFileYouWantToStore.xml. your save save method does not use users file.
public void SaveValues(Values v)
{
XmlSerializer serializer = new XmlSerializer(typeof(Values));
using(TextWriter textWriter = new StreamWriter(#"E:\TheFileYouWantToStore.xml"))
{
serializer.Serialize(textWriter, v);
textWriter.close();
}
...
}
EDIT:
if(savefile1.ShowDialog() == DialogResult.OK)
{
Values v = new Values();
v.task1_name = this.task1_name.Text;
v.task1_desc = this.task1_desc.Text;
v.task1_date = this.task1_date.Value;
v.task1_time = this.task1_time.Value;
SaveValues(savefile1.FileName, v);
}
-
public void SaveValues(string fileName, Values v)
{
XmlSerializer serializer = new XmlSerializer(typeof(Values));
using(TextWriter textWriter = new StreamWriter(fileName))
{
serializer.Serialize(textWriter, v);
textWriter.close();
}
...
}

Related

how to save/load data to n xml file

i'm trying to load and save my data in my datagrid to an xml file using Singleton Design.
i have created
public class DataProvider
{
private static DataProvider singletonInstance = new DataProvider();
private ObservablePerson Person;
/// <summary>
/// Private constructor
/// </summary>
private DataProvider()
{
}
public static DataProvider GetInstance()
{
if (singletonInstance == null)
singletonInstance = new DataProvider();
return singletonInstance;
}
public bool SaveToXml(List<Person> PersonsList)
{
return false;
}
public List<Person> LoadFromX()
{
return new List<Person>() { new Person() { name= "jhon" } };
}
}
}
and this is the object i want to save
[Serializable]
public class ObservablePerson : ObservableObject
{
private string _name;
public string name
{
get
{
return _name;
}
set
{
_name= value;
NotifyPropertyChanged();}
and i also created a view model form from person.
what should i do to save those data in my datagrid in a xml file .
thanks.
Read an XML file using XmlTextReader and call Read method to read its node one by one until the end of file.
using System;
using System.Xml;
namespace ReadXml1 {
class Class1 {
static void Main(string[] args) {
// Create an isntance of XmlTextReader and call Read method to read the file
XmlTextReader textReader = new XmlTextReader("C:\\books.xml");
textReader.Read();
// If the node has value
while (textReader.Read()) {
// Move to fist element
textReader.MoveToElement();
Console.WriteLine("XmlTextReader Properties Test");
Console.WriteLine("===================");
// Read this element's properties and display them on console
Console.WriteLine("Name:" + textReader.Name);
Console.WriteLine("Base URI:" + textReader.BaseURI);
Console.WriteLine("Local Name:" + textReader.LocalName);
Console.WriteLine("Attribute Count:" + textReader.AttributeCount.ToString());
Console.WriteLine("Depth:" + textReader.Depth.ToString());
Console.WriteLine("Line Number:" + textReader.LineNumber.ToString());
Console.WriteLine("Node Type:" + textReader.NodeType.ToString());
Console.WriteLine("Attribute Count:" + textReader.Value.ToString());
}
}
}
}
and for creating and save to XML file:
using System;
using System.Xml;
namespace ReadingXML2 {
class Class1 {
static void Main(string[] args) {
// Create a new file in C:\\ dir
XmlTextWriter textWriter = new XmlTextWriter("C:\\myXmFile.xml", null);
// Opens the document
textWriter.WriteStartDocument();
// Write comments
textWriter.WriteComment("First Comment XmlTextWriter Sample Example");
textWriter.WriteComment("myXmlFile.xml in root dir");
// Write first element
textWriter.WriteStartElement("Student");
textWriter.WriteStartElement("r", "RECORD", "urn:record");
// Write next element
textWriter.WriteStartElement("Name", "");
textWriter.WriteString("Student");
textWriter.WriteEndElement();
// Write one more element
textWriter.WriteStartElement("Address", "");
textWriter.WriteString("Colony");
textWriter.WriteEndElement();
// WriteChars
char[] ch = new char[3];
ch[0] = 'a';
ch[1] = 'r';
ch[2] = 'c';
textWriter.WriteStartElement("Char");
textWriter.WriteChars(ch, 0, ch.Length);
textWriter.WriteEndElement();
// Ends the document.
textWriter.WriteEndDocument();
// close writer
textWriter.Close();
}
}
}
Let's use Xml and Xml.Serialization:
using System.Xml;
using System.Xml.Serialization;
On your singleton, implements
public static List<T> LoadFromXml<T>(string path, string fileName)
{
var xmlSerializer = new XmlSerializer(typeof(List<T>));
var xmlText = File.ReadAllText(Path.Combine(path, fileName));
return (List<T>)xmlSerializer.Deserialize(new StringReader(xmlText));
}
public static bool SaveToXml<T>(List<T> list, string path, string fileName)
{
var xmlText = Serialize<T>(list);
try
{
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
File.WriteAllText(Path.Combine(path, fileName), xmlText);
return true;
}
catch(Exception e)
{
return false;
}
}
private static string Serialize<T>(List<T> list)
{
if (list == null || !list.Any())
return string.Empty;
var xmlSerializer = new XmlSerializer(typeof(List<T>));
using (var stringWriter = new StringWriter())
{
using (var xmlWriter = XmlWriter.Create(stringWriter, new XmlWriterSettings { Indent = true }))
{
xmlSerializer.Serialize(xmlWriter, list);
return stringWriter.ToString();
}
}
}
Using generic T, we can use the same methods to save other types of records
To call:
var person1 = new Person()
{
name = "jhon",
};
var person2 = new Person()
{
name = "another jhon",
};
var personList = new List<Person>();
personList.Add(person1);
personList.Add(person2);
var pathXml = #"C:\testes\xml";
var fileName = "persons.xml";
var dataProvider = DataProvider.GetInstance();
var itsSaved = dataProvider.SaveToXml<Person>(personList, pathXml, fileName);
var persons = dataProvider.LoadFromXml<Person>(pathXml, fileName);

issue reading from xml file c#

I am trying to read from a xml file but it is not working eventhough I have been weating over it for two days, so any help would be greatly appreciated!
In Cookbook class:
public List<Recipe> readAll()
{
List<Recipe> newListRecipies = new List<Recipe>();
Recipe readRecipie = new Recipe();
TextReader reader = null;
try
{
var serializer = new XmlSerializer(typeof(Recipe));
reader = new StreamReader(path);
newListRecipies = BinarySerialization.ReadFromBinaryFile<List<Recipe>>(path);
reader.Close();
return newListRecipies;
}
catch (Exception e)
{
string error = $"An exception occured: " + e;
Log theLog = new Log();
theLog.LogMessage(error);
return newListRecipies;
}
}
In Recipe class:
public Recipe readOne(string name)
{
CookBook newCB = new CookBook();
List<Recipe> allRecipies = newCB.readAll();
foreach(Recipe oneRecipe in allRecipies)
{
if(oneRecipe.recipeName == name)
{
return oneRecipe;
}
}return newCB.defaultRecipie;
}
I am getting the default recipe as the result everytime. I can see the the recipies are saved correctly everytime but here the code anyways:
In Recipie class:
public void SaveRecipe(Recipe myRecepie)
{
CookBook theCookBook = new CookBook();
theCookBook.Save(myRecepie);
addFoodItem(myRecepie.recipeIngridients);
}
In CookBook class:
public void Save(Recipe newRecipie)
{
TextWriter writer = null;
try
{
var serializer = new XmlSerializer(typeof(Recipe));
writer = new StreamWriter(path, append: true);
serializer.Serialize(writer, newRecipie);
}
finally
{
if (writer != null)
writer.Close();
}
}
And the xml file (generated by the save function in the CookBook class)
<?xml version="1.0" encoding="utf-8"?>
<Recipe xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<recipeName>toast</recipeName>
<recipeType>snack</recipeType>
<recipeIngridients>
<string>bread</string>
<string>butter</string>
</recipeIngridients>
</Recipe><?xml version="1.0" encoding="utf-8"?>
<Recipe xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<recipeName>G&T</recipeName>
<recipeType>drink</recipeType>
<recipeIngridients>
<string>tonic</string>
<string>gin</string>
</recipeIngridients>
</Recipe><?xml version="1.0" encoding="utf-8"?>
<Recipe xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<recipeName>cake</recipeName>
<recipeType>snack</recipeType>
<recipeIngridients>
<string>butter</string>
<string>sugar</string>
</recipeIngridients>
</Recipe>
I believe the way you are deserializing the xml is incorrect with BinarySerialization.ReadFromBinaryFile....
Assuming your xml is correct I would do something like this.
// read file
List<Recipe> recipes;
using (var reader = new StreamReader("recipe.xml"))
{
XmlSerializer deserializer = new XmlSerializer(typeof(List<Recipe>),
new XmlRootAttribute("Recipe"));
recipes = (List<Recipe>)deserializer.Deserialize(reader);
}
These are the changes I made. It's best to load the previous recipes, add to the list, then re-write the XML from scratch.
public class Recipe
{
public string recipeName;
public string recipeType;
public List<string> recipeIngridients = new List<string>();
public Recipe readOne(string name)
{
CookBook newCB = new CookBook();
List<Recipe> allRecipies = newCB.readAll();
foreach(Recipe oneRecipe in allRecipies)
{
if(oneRecipe.recipeName == name)
{
return oneRecipe;
}
}
return newCB.defaultRecipe;
}
}
public class RecipeList
{
public List<Recipe> Recipes = new List<Recipe>();
}
public class CookBook
{
public Recipe defaultRecipe;
public string path;
public void Save(Recipe newRecipe)
{
TextWriter writer = null;
RecipeList recipeList = null;
try
{
// See if recipes exists
var serializer = new XmlSerializer(typeof(RecipeList));
if (File.Exists(path)) // Load the recipe list if it exists
{
using (var fileStream = File.OpenRead(path))
{
recipeList = (RecipeList)serializer.Deserialize(fileStream);
}
}
else
{
recipeList = new RecipeList();
}
// Add recipe to the list
recipeList.Recipes.Add(newRecipe);
writer = new StreamWriter(path, append: false);
serializer.Serialize(writer, recipeList);
}
finally
{
if (writer != null)
writer.Close();
}
}
public List<Recipe> readAll()
{
RecipeList temp = null;
var serializer = new XmlSerializer(typeof(RecipeList));
try
{
using (var fileStream = File.OpenRead(path))
{
temp = (RecipeList)serializer.Deserialize(fileStream);
}
return temp.Recipes;
}
catch (Exception e)
{
string error = #"An exception occured: " + e;
//Log theLog = new Log();
//theLog.LogMessage(error);
return new List<Recipe>();
}
}
}

Deserialize object from binary file

Hey guys I am working on a program that will take a person's name and comment and then serialize it to a binary file. It must also be able to deserialize and load the data to the form. I need it to be able to go up and down the list of files(names and comments) by using buttons on the form.
In my code I have it separated into a class that builds the object and the code for the form, and no i'm not allowed to separate it. (Just in case anyone thought that'd work)
the form code:
private void btnAdd_Click(object sender, EventArgs e)
{
bool blnValid = true;
if (string.IsNullOrWhiteSpace(txtName.Text))
{
MessageBox.Show("Please enter a valid name");
}
if (string.IsNullOrWhiteSpace(txtComment.Text))
{
MessageBox.Show("Please enter a valid comment");
blnValid = false;
}
if (blnValid)
{
//create class instance and assign property values
//set file name
DateTime CurrentDate = DateTime.Now;
string strFileName;
strFileName = CurrentDate.ToString("dd-MM-yy-hh-mm-ss") + ".bin";
// serialize object to binary file
MessageBox.Show(strFileName);
Enquiry newEnquiry = new Enquiry();
newEnquiry.Name = txtName.Text;
newEnquiry.Comment = txtComment.Text;
newEnquiry.DOB = dteDOB.Value;
newEnquiry.WriteToFile(strFileName, newEnquiry);
}
}
private void btnLoad_Click(object sender, EventArgs e)
{
}
private void btnPrevious_Click(object sender, EventArgs e)
{
}
and the class code:
[Serializable]
class Enquiry
{
//stores the various values into the enquiry class.
public string Name { get; set; }
public DateTime DOB { get; set; }
public string Comment { get; set; }
//creates the file, if there isn't one, writes the file, and
//disables sharing while the program is active. It also formats
//the file into binary
public void WriteToFile(string strFileName, Enquiry newEnquiry)
{
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream(strFileName, FileMode.Create, FileAccess.Write, FileShare.None);
formatter.Serialize(stream, newEnquiry);
stream.Close();
}
// this loads the files and translates them to plain text
public void ReadFromFile(string strFileName, Enquiry newEnquiry)
{
Stream stream = File.OpenRead(strFileName);
BinaryFormatter formatter = new BinaryFormatter();
newEnquiry = (Enquiry)formatter.Deserialize(stream);
stream.Close();
}
I don't know what you are asking, but if you need methods to serialize and deserialize, use these:
public static void BinarySerializeObject(string path, object obj)
{
using (StreamWriter streamWriter = new StreamWriter(path))
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
try
{
binaryFormatter.Serialize(streamWriter.BaseStream, obj);
}
catch (SerializationException ex)
{
throw new SerializationException(((object) ex).ToString() + "\n" + ex.Source);
}
}
}
public static object BinaryDeserializeObject(string path)
{
using (StreamReader streamReader = new StreamReader(path))
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
object obj;
try
{
obj = binaryFormatter.Deserialize(streamReader.BaseStream);
}
catch (SerializationException ex)
{
throw new SerializationException(((object) ex).ToString() + "\n" + ex.Source);
}
return obj;
}
}

how to Same tags for c#Entity to Xml

i have question!!
=============normal===========
class trx()
{
string trx_name;
string type_id;
}
var 0 = new trx(){trx_name="1",trx_name="2"}
---Entity change to xml
[XmlSerializer serializer = new XmlSerializer(typeof(trx));
[serializer.Serialize(File.OpenWrite(#".\MyXml.xml"), o);]
----XML result------
<trx>
<trx_name>1</trx_name>
<type_id>2</type_id>
</trx>
=============================
Q: but i need trx XML
<trx>
<trx_name>a</trx_name>
<trx_name>b</trx_name>
<trx_name>c</trx_name>
<trx_name>d</trx_name>
</trx>
how to solve the question???
Thanks in advance for your help
Something like this.
public class trx
{
public string trx_name { get; set; }
}
public class CustomSerializer
{
private static void Write(string filename)
{
List<trx> trxs = new List<trx>();
trxs.Add(new trx {trx_name = "Name1"});
trxs.Add(new trx {trx_name = "Name2"});
XmlSerializer x = new XmlSerializer(typeof (List<trx>));
TextWriter writer = new StreamWriter(filename);
x.Serialize(writer, trxs);
}
private static List<trx> Read(string filename)
{
var x = new XmlSerializer(typeof (List<trx>));
TextReader reader = new StreamReader(filename);
return (List<trx>) x.Deserialize(reader);
}
}
}

Binary Serialization, I think I almost have it working

I've been following a guide on Binary Serialization (this one here: http://www.codeproject.com/Articles/1789/Object-Serialization-using-C) and I think I finally almost have it working. When I save the file is created, but when I try to load, nothing is loaded. I feel like I'm close to getting this working. Any advice would be appreciated. Here's the code:
Save/Load class
[Serializable()]
public class SaveLoad : ISerializable
{
public int GameDay = Date.GameDay;
public List<Adventurer> Adventurers = FormMain.AdventurerManager.AdventurerList;
public SaveLoad()
{
GameDay = 0;
Adventurers = null;
}
public SaveLoad(SerializationInfo info, StreamingContext ctxt)
{
GameDay = (int)info.GetValue("Date", typeof(int));
Adventurers = (List<Adventurer>)info.GetValue("Adventurers", typeof(List<Adventurer>));
}
public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
{
info.AddValue("Date", GameDay);
info.AddValue("Adventurers", Adventurers);
}
}
Save/Load methods:
void btnSaveGame_Click(object sender, EventArgs e)
{
SaveLoad save = new SaveLoad();
Stream stream = File.Open("SaveGame.osl", FileMode.Create);
BinaryFormatter bformatter = new BinaryFormatter();
bformatter.Serialize(stream, save);
stream.Close();
}
void btnLoadGame_Click(object sender, EventArgs e)
{
SaveLoad load = new SaveLoad();
Stream stream = File.Open("SaveGame.osl", FileMode.Open);
BinaryFormatter bformatter = new BinaryFormatter();
load = (SaveLoad)bformatter.Deserialize(stream);
stream.Close();
Date.CalculateDate();
this.Visible = false;
((FormMain)(this.ParentForm)).ControlMainScreen.Visible = true;
}
I think you may just have an initialization timing issue.
Try either moving you initialization of the GameDay and Adventurers to the constructor or get rid of the nulling them out in the constructor. Once I did the following, the code pretty much works:
public SaveLoad()
{
//GameDay = null;
//Adventurers = null;
}
Note I had to also make sure that the Adventurer class had the Serialization attribute.
Here is the code with the serialization that works for me (I had to create my own Adventurer class and I replaced the date with a string since I couldn't figure out what you were doing with it or where it was coming from. I also populated the adventurers list with some dummy data and commented out anything to do with the form stuff that I also didn't have information on.
[Serializable()]
public class SaveLoad : ISerializable
{
public string GameDay = null;
public List<Adventurer> Adventurers = null;
//FormMain.AdventurerManager.AdventurerList;
public SaveLoad()
{
GameDay = "Date";
Adventurers = new List<Adventurer>() { new Adventurer { Name = "a1", Type = "t1" }, new Adventurer { Name = "a1", Type = "t1" } }; ;
}
public SaveLoad(SerializationInfo info, StreamingContext ctxt)
{
GameDay = (string)info.GetValue("Date", typeof(string));
Adventurers = (List<Adventurer>)info.GetValue("Adventurers", typeof(List<Adventurer>));
}
public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
{
info.AddValue("Date", GameDay);
info.AddValue("Adventurers", Adventurers);
}
}
[Serializable()]
public class Adventurer
{
public string Name { get; set; }
public string Type { get; set; }
}
private void btnLoadGame_Click(object sender, EventArgs e)
{
SaveLoad sl = new SaveLoad();
Stream stream = File.Open("SaveGame.osl", FileMode.Open);
BinaryFormatter bformatter = new BinaryFormatter();
sl = (SaveLoad)bformatter.Deserialize(stream);
stream.Close();
MessageBox.Show(sl.Adventurers.Count.ToString());
//Date.CalculateDate();
//this.Visible = false;
//((Form1)(this.ParentForm)).ControlMainScreen.Visible = true;
}
private void btnSaveGame_Click(object sender, EventArgs e)
{
SaveLoad sl = new SaveLoad();
Stream stream = File.Open("SaveGame.osl", FileMode.Create);
BinaryFormatter bformatter = new BinaryFormatter();
bformatter.Serialize(stream, sl);
stream.Close();
}
EDIT
#JasonHaley is right, you have a timing/initialization issue.
During your Load button click event your defining a new SaveLoad called "Load"
This creates a reference to the FormMain.AdventurerManager.AdventurerList
But during deserialization this reference is destroyed by the object that was serialized to disk (the other list of adventurers) and is now a DIFFERENT list of adventurers from the one defined in your FormMain.AdventurerManager.AdventurerList
You need to load into that list specifically...
void btnLoadGame_Click(object sender, EventArgs e)
{
Stream stream = File.Open("SaveGame.osl", FileMode.Open);
BinaryFormatter bformatter = new BinaryFormatter();
SaveLoad load = (SaveLoad)bformatter.Deserialize(stream);
// ***********************************
FormMain.AdventurerManager.AdventurerList = SaveLoad.Adventurers
// ***********************************
stream.Close();
Date.CalculateDate();
this.Visible = false;
((FormMain)(this.ParentForm)).ControlMainScreen.Visible = true;
}

Categories