After serialization sometimes xml files is filled with empty spaces. Why is it happen?
My serialization code is:
XmlSerializer serializer = new XmlSerializer(typeof(SerializableStorage));
using (StreamWriter sw = new StreamWriter(storageName, false, myEncoding))
{
serializer.Serialize(sw, messages);
}
This code serializes me messages into XML.
SerializableStorage looks like:
[XmlRoot("Storage")]
public class SerializableStorage
{
/// <summary>
/// Gets or sets an array of server messages
/// </summary>
[XmlArray("Messages")]
[XmlArrayItem("Message")]
public List<NMessage> Messages
{
get;
protected set;
}
/// <summary>
/// Public constructor
/// </summary>
public SerializableStorage()
{
Messages = new List<NMessage>();
}
}
NMessage class has all fields as public.
And deserialization if needed:
XmlSerializer serializer = new XmlSerializer(typeof(SerializableStorage));
StreamReader reader = new StreamReader(storageName, myEncoding);
StoreMessages = (SerializableStorage)serializer.Deserialize(reader);
reader.Close();
I've attached an "empty xml" example here
Related
private void SMSend_Clicked(object sender, EventArgs e)
{
var text = myeditor.Text;
}
I am trying to create a sms sender project with Xamarin. And text will be send through api.So i need to convert the text to xml. I am holding the text in the "text" field. I need to convert this text into the xml sytle like converting to JSON. I found something like
var xml = new XmlSerializer(typeof());
but I don't know if it is right to use.And I dont know how to implement these methods. Thank you for helping me!
You can just create a method to convert your text to xml as string.
Something like this will work:
var serializer = new XmlSerializer(typeof(T));
var sw = new Utf8StringWriter();
serializer.Serialize(sw, typeOfObjectToConvert);
ret = sw.ToString();
T is here the type of Object that you want to serliaze to xml.
I create a method for you that you can try :
/// <summary>
/// Converts an object to xml string
/// </summary>
/// <typeparam name="T">the type of the object</typeparam>
/// <param name="typeOfObjectToConvert">the object that needs to be serialized</param>
/// <returns>xml string</returns>
public static string ConvertObjectToPlainXmlString<T>(
T typeOfObjectToConvert)
{
var serializer = new XmlSerializer(typeof(T));
var sw = new Utf8StringWriter();
serializer.Serialize(sw, typeOfObjectToConvert);
return sw.ToString();
}
As an example :
public class MyConfig{
public string TransferUrl {get; set;}
public string TransferData {get; set;}
//.. all properties
}
Than just call method like this:
var xmlString = ConvertObjectToPlainXmlString(MyConfig);
I am trying to make a winform application. The app has 2 textboxes (firstName, lastName), a numericUpDown, and a checkbox. The app is able to read from a text file, with comma separated rows (Daniel,Brown,26,true). The app put this info in a listbox. Then you can add a new user. When you are finished adding users you press save and the new info from lisbox will be saved in that text file. I've created the read file script and add user succesfully. However I can't create the save user button so that it'll save: Daniel,Brown,26,true. I was able to save as: Daniel,Brown,26,happy.
Here is the Person Class:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Age { get; set; }
public bool IsHappy { get; set; }
public override string ToString()
{
var statusText = IsHappy ? "happy" : "not happy";
return $"{FirstName} {LastName} is {Age} and is {statusText}";
}
}
Here is the form.cs with it's script:
public partial class ChallengeForm : Form
{
private BindingList<Person> _persons = new BindingList<Person>();
private PersonsService _personsService;
public ChallengeForm()
{
_personsService = new PersonsService();
InitializeComponent();
WireUpDropDown();
}
private void WireUpDropDown()
{
_persons = new BindingList<Person>(_personsService.GetPersons(#"C:\Users\user\Desktop\Document.TXT"));
usersListBox.DataSource = _persons;
}
private void addUserButton_Click(object sender, EventArgs e)
{
var person = new Person { FirstName = firstNameText.Text, LastName = lastNameText.Text, Age = agePicker.Text, IsHappy = isHappyCheckbox.Checked };
_persons.Add(person);
}
private void saveListButton_Click(object sender, EventArgs e)
{
}
}
My question is how can I convert the status back to bool. And write the listbox to the text file as csv. I would be very thankfull if you could use SoC.
Here is what I've tried:
const string sPath = (#"C:\Users\user\Desktop\Document.TXT");
System.IO.StreamWriter SaveFile = new System.IO.StreamWriter(sPath);
SaveFile.Write(myperson);
foreach (var item in usersListBox.Items)
{
List<string> unwantedWords = new List<string> { "is", "and" };
var linesSplitted = item.ToString().Split(' ').ToList();
var wordsWithoutUnwantedWords = linesSplitted.Where(i => !unwantedWords.Contains(i)).ToList();
for (int i = 0; i<wordsWithoutUnwantedWords.Count; i++)
{
var isLastWord = i == wordsWithoutUnwantedWords.Count - 1;
SaveFile.Write(wordsWithoutUnwantedWords[i]);
if (!isLastWord)
{
SaveFile.Write(",");
}
Look into XML Serialization. You can just pass in your filepath and the object and the rest will be done for you by the Serialisation classes. Code below:
This is taken from DeadlyDog's awesome answer: https://stackoverflow.com/a/22417240/1623971
/// <summary>
/// Writes the given object instance to an XML file.
/// <para>Only Public properties and variables will be written to the file. These can be any type though, even other classes.</para>
/// <para>If there are public properties/variables that you do not want written to the file, decorate them with the [XmlIgnore] attribute.</para>
/// <para>Object type must have a parameterless constructor.</para>
/// </summary>
/// <typeparam name="T">The type of object being written to the file.</typeparam>
/// <param name="filePath">The file path to write the object instance to.</param>
/// <param name="objectToWrite">The object instance to write to the file.</param>
/// <param name="append">If false the file will be overwritten if it already exists. If true the contents will be appended to the file.</param>
public static void WriteToXmlFile<T>(string filePath, T objectToWrite, bool append = false) where T : new()
{
TextWriter writer = null;
try
{
var serializer = new XmlSerializer(typeof(T));
writer = new StreamWriter(filePath, append);
serializer.Serialize(writer, objectToWrite);
}
finally
{
if (writer != null)
writer.Close();
}
}
/// <summary>
/// Reads an object instance from an XML file.
/// <para>Object type must have a parameterless constructor.</para>
/// </summary>
/// <typeparam name="T">The type of object to read from the file.</typeparam>
/// <param name="filePath">The file path to read the object instance from.</param>
/// <returns>Returns a new instance of the object read from the XML file.</returns>
public static T ReadFromXmlFile<T>(string filePath) where T : new()
{
TextReader reader = null;
try
{
var serializer = new XmlSerializer(typeof(T));
reader = new StreamReader(filePath);
return (T)serializer.Deserialize(reader);
}
finally
{
if (reader != null)
reader.Close();
}
}
Sample use case:
WriteToXmlFile<Person>("C:\someClass.txt", objectToSerialize);
// Read the file contents back into a variable.
Person deserializedObject = ReadFromXmlFile<Person>("C:\someClass.txt");
I'm basically looking for someone to point me in the right direction on this. I read through some of the Microsoft documentation, but that wasn't very helpful. This is my first attempt at working with XML.
I'm writing an application that needs to store a list of known users and a list of aliases created by each of those users. I've figured out how to have my lists serialized and stored to XML files when the application closes and have it retrieve those when the application opens again, but I don't want to keep the list of users and aliases in memory.
In order for this to work, I need to have the ability to search, edit, and append to the XML file during run time.
The XML structure I envision is something like:
<UserRecord>
<User>Username-1</User>
<AliasRecord>
<Alias>Alias-1</Alias>
<Number>6135551234</Number>
</AliasRecord>
<AliasRecord>
<Alias>Alias-2</Alias>
<Number>6131238888</Number>
</AliasRecord>
</UserRecord>
Each user would only have one username but could have multiple aliases. I need to have the ability to add users, add aliases to a new or existing user, and change existing aliases. Usernames would never change, but an entire User record could be deleted.
So far, the only XML I've done in C# uses serialization but I don't think that approach will work for the above.
private void WriteXML()
{
try
{
System.Xml.Serialization.XmlSerializer XMLwriter = new System.Xml.Serialization.XmlSerializer(typeof(MessageRecord));
System.IO.StreamWriter XMLfile = new System.IO.StreamWriter("Saved MessageRecords.xml");
foreach (MessageRecord mr in OutgoingMessages)
{
XMLwriter.Serialize(XMLfile, mr);
}
XMLfile.Close();
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
Create two classes to represent UserRecord and AliasRecord.
public class UserRecord
{
public string User { get; set; }
public List<AliasRecord> AliasRecords { get; set; }
}
public class AliasRecord
{
public string Alias { get; set; }
public string Number { get; set; }
}
Populate them like this:
var userRecord = new UserRecord
{
User = "UserName1",
AliasRecord = new List<AliasRecord> {
new AliasRecord { Alias = "Alias1", Number = "12345678" },
new AliasRecord { Alias = "Alias2", Number = "23456789" }
}
};
And use this code to serialize/deserialize it:
public static class XmlHelper
{
public static bool NewLineOnAttributes { get; set; }
/// <summary>
/// Serializes an object to an XML string, using the specified namespaces.
/// </summary>
public static string ToXml(object obj, XmlSerializerNamespaces ns)
{
Type T = obj.GetType();
var xs = new XmlSerializer(T);
var ws = new XmlWriterSettings { Indent = true, NewLineOnAttributes = NewLineOnAttributes, OmitXmlDeclaration = true };
var sb = new StringBuilder();
using (XmlWriter writer = XmlWriter.Create(sb, ws))
{
xs.Serialize(writer, obj, ns);
}
return sb.ToString();
}
/// <summary>
/// Serializes an object to an XML string.
/// </summary>
public static string ToXml(object obj)
{
var ns = new XmlSerializerNamespaces();
ns.Add("", "");
return ToXml(obj, ns);
}
/// <summary>
/// Deserializes an object from an XML string.
/// </summary>
public static T FromXml<T>(string xml)
{
XmlSerializer xs = new XmlSerializer(typeof(T));
using (StringReader sr = new StringReader(xml))
{
return (T)xs.Deserialize(sr);
}
}
/// <summary>
/// Deserializes an object from an XML string, using the specified type name.
/// </summary>
public static object FromXml(string xml, string typeName)
{
Type T = Type.GetType(typeName);
XmlSerializer xs = new XmlSerializer(T);
using (StringReader sr = new StringReader(xml))
{
return xs.Deserialize(sr);
}
}
/// <summary>
/// Serializes an object to an XML file. (Fixed code)
/// </summary>
public static void ToXmlFile(object obj, string filePath)
{
var xs = new XmlSerializer(obj.GetType());
var ns = new XmlSerializerNamespaces();
var ws = new XmlWriterSettings { Indent = true, NewLineOnAttributes = NewLineOnAttributes, OmitXmlDeclaration = true };
ns.Add("", "");
using (XmlWriter writer = XmlWriter.Create(filePath, ws))
{
xs.Serialize(writer, obj, ns);
}
}
/// <summary>
/// Deserializes an object from an XML file.
/// </summary>
public static T FromXmlFile<T>(string filePath)
{
StreamReader sr = new StreamReader(filePath);
try
{
var result = FromXml<T>(sr.ReadToEnd());
return result;
}
catch (Exception e)
{
throw new Exception("There was an error attempting to read the file " + filePath + "\n\n" + e.InnerException.Message);
}
finally
{
sr.Close();
}
}
}
Example usage:
var result = XmlHelper.ToXml(userRecord);
Result:
<UserRecord>
<User>Username1</User>
<AliasRecords>
<AliasRecord>
<Alias>Alias1</Alias>
<Number>12345678</Number>
</AliasRecord>
<AliasRecord>
<Alias>Alias2</Alias>
<Number>23456789</Number>
</AliasRecord>
</AliasRecords>
</UserRecord>
I have been trying to add new list items with attachments to my list .
The list items are added fine, however I cannot figure out how to attach files to those items
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ConsoleApplication3.TestReference;
using System.IO;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
MVSDataContext dc = new MVSDataContext(
new Uri("https:xxx_vti_bin/ListData.svc"));
dc.Credentials = System.Net.CredentialCache.DefaultCredentials;
TestListItem newItem = new TestListItem { Title = "test6" };
dc.AddToTestList(newItem);
dc.SaveChanges();
/* up to this point everything works fine and i am able to add a new list item */
FileStream fStream = File.OpenRead("C:\\xxxxx.xlsx");
string fileName = fStream.Name.Substring(3);
byte[] contents = new byte[fStream.Length];
fStream.Read(contents, 0, (int)fStream.Length);
fStream.Close();
/* the file read successfuly . Now I should use `contents` to upload the file */
newItem.Attachments.Add(fStream.Name, contents); /* This line does not compile */
dc.SaveChanges();
}
}
}
}
I also tried approach from here
DirectoryInfo attachmentDirectory = new DirectoryInfo(#"C:\xxx");
FileInfo[] attachments = attachmentDirectory.GetFiles();
foreach (FileInfo attachment in attachments)
{
FileStream fs = new FileStream(attachment.FullName, FileMode.Open, FileAccess.Read);
// Create a byte array of file stream length
byte[] ImageData = new byte[fs.Length];
//Read block of bytes from stream into the byte array
fs.Read(ImageData, 0, System.Convert.ToInt32(fs.Length));
//Close the File Stream
fs.Close();
newItem.Attachments.Add(attachment.Name, ImageData);
}
However got the same error
How can I make an attachment to a list item ?
Here is the TestListItem class
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.18052
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
// Original file name:
// Generation date: 1/30/2014 11:00:30 AM
namespace ConsoleApplication3.TestReference
{
/// <summary>
/// There are no comments for MVSDataContext in the schema.
/// </summary>
public partial
class MVSDataContext : global::System.Data.Services.Client.DataServiceContext
{
/// <summary>
/// Initialize a new MVSDataContext object.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
public MVSDataContext(global::System.Uri serviceRoot) :
base(serviceRoot)
{
this.ResolveName = new global::System.Func<global::System.Type, string>(this.ResolveNameFromType);
this.ResolveType = new global::System.Func<string, global::System.Type>(this.ResolveTypeFromName);
this.OnContextCreated();
}
partial void OnContextCreated();
/// <summary>
/// Since the namespace configured for this service reference
/// in Visual Studio is different from the one indicated in the
/// server schema, use type-mappers to map between the two.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
protected global::System.Type ResolveTypeFromName(string typeName)
{
if (typeName.StartsWith("Microsoft.SharePoint.DataService", global::System.StringComparison.Ordinal))
{
return this.GetType().Assembly.GetType(string.Concat("ConsoleApplication3.TestReference", typeName.Substring(32)), false);
}
return null;
}
/// <summary>
/// Since the namespace configured for this service reference
/// in Visual Studio is different from the one indicated in the
/// server schema, use type-mappers to map between the two.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
protected string ResolveNameFromType(global::System.Type clientType)
{
if (clientType.Namespace.Equals("ConsoleApplication3.TestReference", global::System.StringComparison.Ordinal))
{
return string.Concat("Microsoft.SharePoint.DataService.", clientType.Name);
}
return null;
}
/// <summary>
/// There are no comments for Attachments in the schema.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
public global::System.Data.Services.Client.DataServiceQuery<AttachmentsItem> Attachments
{
get
{
if ((this._Attachments == null))
{
this._Attachments = base.CreateQuery<AttachmentsItem>("Attachments");
}
return this._Attachments;
}
}
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
private global::System.Data.Services.Client.DataServiceQuery<AttachmentsItem> _Attachments;
/// <summary>
/// There are no comments for MasterPageGallery in the schema.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
public global::System.Data.Services.Client.DataServiceQuery<MasterPageGalleryItem> MasterPageGallery
{
get
{
if ((this._MasterPageGallery == null))
{
this._MasterPageGallery = base.CreateQuery<MasterPageGalleryItem>("MasterPageGallery");
}
return this._MasterPageGallery;
}
}
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
private global::System.Data.Services.Client.DataServiceQuery<MasterPageGalleryItem> _MasterPageGallery;
/// <summary>
/// There are no comments for MasterPageGalleryCompatibleUIVersionS in the schema.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
public global::System.Data.Services.Client.DataServiceQuery<MasterPageGalleryCompatibleUIVersionSValue> MasterPageGalleryCompatibleUIVersionS
{
get
{
if ((this._MasterPageGalleryCompatibleUIVersionS == null))
{
this._MasterPageGalleryCompatibleUIVersionS = base.CreateQuery<MasterPageGalleryCompatibleUIVersionSValue>("MasterPageGalleryCompatibleUIVersionS");
}
return this._MasterPageGalleryCompatibleUIVersionS;
}
}
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
private global::System.Data.Services.Client.DataServiceQuery<MasterPageGalleryCompatibleUIVersionSValue> _MasterPageGalleryCompatibleUIVersionS;
/// <summary>
/// There are no comments for TestList in the schema.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
public global::System.Data.Services.Client.DataServiceQuery<TestListItem> TestList
{
get
{
if ((this._TestList == null))
{
this._TestList = base.CreateQuery<TestListItem>("TestList");
}
return this._TestList;
}
}
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
private global::System.Data.Services.Client.DataServiceQuery<TestListItem> _TestList;
/// <summary>
/// There are no comments for UserInformationList in the schema.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
public global::System.Data.Services.Client.DataServiceQuery<UserInformationListItem> UserInformationList
{
get
{
if ((this._UserInformationList == null))
{
this._UserInformationList = base.CreateQuery<UserInformationListItem>("UserInformationList");
}
return this._UserInformationList;
}
}
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
private global::System.Data.Services.Client.DataServiceQuery<UserInformationListItem> _UserInformationList;
/// <summary>
/// There are no comments for Attachments in the schema.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
public void AddToAttachments(AttachmentsItem attachmentsItem)
{
base.AddObject("Attachments", attachmentsItem);
}
/// <summary>
/// There are no comments for MasterPageGallery in the schema.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
public void AddToMasterPageGallery(MasterPageGalleryItem masterPageGalleryItem)
{
base.AddObject("MasterPageGallery", masterPageGalleryItem);
}
/// <summary>
/// There are no comments for MasterPageGalleryCompatibleUIVersionS in the schema.
/// </summary>
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
public void AddToMasterPageGalleryCompatibleUIVersionS(MasterPageGalleryCompatibleUIVersionSValue masterPageGalleryCompatibleUIVersionSValue)
{
base.AddObject("MasterPageGalleryCompatibleUIVersionS", masterPageGalleryCompatibleUIVersionSValue);
}
/// <summary>
/// There are no comments for TestList in the schema.
/// </summary>
..............
Have you got the code for TestListItem? It looks pretty clearly like Add requires 2 arguments to be passed into it.
You need to add the byte stream for the file you want to add - see here
foreach (FileInfo attachment in attachments)
{
FileStream fs = new FileStream(attachment.FullName , FileMode.Open,FileAccess.Read);
// Create a byte array of file stream length
byte[] ImageData = new byte[fs.Length];
//Read block of bytes from stream into the byte array
fs.Read(ImageData,0,System.Convert.ToInt32(fs.Length));
//Close the File Stream
fs.Close();
item.Attachments.Add(attachment.Name, ImageData);
}
Call the Method AddQueryOption instead of Add:
newItem.Attachments.Add(fStream.Name, contents); /* This line does not compile */
newItem.Attachments.AddQueryOption(fStream.Name, contents); /* This line does compile */
Hope this helps other users.
The problem here is that the SharePoint Client Object Model does not create the item's sub-folder under the Attachments folder.
To solve this you should use the "/_vti_bin/lists.asmx" web service by adding a Web Service Reference, please follow this link in case you need indications to achieve it.
using FR.WssODataCore.ListsWebService;
Once you added the reference to your service you can just use this code snippet:
var listsServiceClient = new Lists
{
Credentials = defaultContext.Credentials,
Url = siteCollectionUrl + "/_vti_bin/lists.asmx"
};
listsServiceClient.AddAttachment(currentListName, listItemId, fileName, fileContent);
Where siteCollectionUrl is your service's url like http://yourSite.ext/webName, and defaultContext is an instance of Microsoft.SharePoint.Client which I've used to complete other actions.
Please, note that you need a reference to your web service reference that contains the Lists object
using MyServiceNameSpace.ListsWebService;
In this way, I was able to use both the ListData.svc and Lists.asmx endpoints by combining the operations, using the .asmx service only to upload the attachment.
Here another good resource.
I've got a class salesman in the following format:
class salesman
{
public string name, address, email;
public int sales;
}
I've got another class where the user inputs name, address, email and sales.
This input is then added to a list
List<salesman> salesmanList = new List<salesman>();
After the user has input as many salesman to the list as they like, they have the option to save the list to a file of their choice (which I can limit to .xml or .txt(which ever is more appropriate)).
How would I add this list to the file?
Also this file needs to be re-read back into a list if the user wishes to later view the records.
Something like this would work. this uses a binary format (the fastest for loading) but the same code would apply to xml with a different serializer.
using System.IO;
[Serializable]
class salesman
{
public string name, address, email;
public int sales;
}
class Program
{
static void Main(string[] args)
{
List<salesman> salesmanList = new List<salesman>();
string dir = #"c:\temp";
string serializationFile = Path.Combine(dir, "salesmen.bin");
//serialize
using (Stream stream = File.Open(serializationFile, FileMode.Create))
{
var bformatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
bformatter.Serialize(stream, salesmanList);
}
//deserialize
using (Stream stream = File.Open(serializationFile, FileMode.Open))
{
var bformatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
List<salesman> salesman = (List<salesman>)bformatter.Deserialize(stream);
}
}
}
I just wrote a blog post on saving an object's data to Binary, XML, or Json; well writing an object or list of objects to a file that is. Here are the functions to do it in the various formats. See my blog post for more details.
Binary
/// <summary>
/// Writes the given object instance to a binary file.
/// <para>Object type (and all child types) must be decorated with the [Serializable] attribute.</para>
/// <para>To prevent a variable from being serialized, decorate it with the [NonSerialized] attribute; cannot be applied to properties.</para>
/// </summary>
/// <typeparam name="T">The type of object being written to the XML file.</typeparam>
/// <param name="filePath">The file path to write the object instance to.</param>
/// <param name="objectToWrite">The object instance to write to the XML file.</param>
/// <param name="append">If false the file will be overwritten if it already exists. If true the contents will be appended to the file.</param>
public static void WriteToBinaryFile<T>(string filePath, T objectToWrite, bool append = false)
{
using (Stream stream = File.Open(filePath, append ? FileMode.Append : FileMode.Create))
{
var binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
binaryFormatter.Serialize(stream, objectToWrite);
}
}
/// <summary>
/// Reads an object instance from a binary file.
/// </summary>
/// <typeparam name="T">The type of object to read from the XML.</typeparam>
/// <param name="filePath">The file path to read the object instance from.</param>
/// <returns>Returns a new instance of the object read from the binary file.</returns>
public static T ReadFromBinaryFile<T>(string filePath)
{
using (Stream stream = File.Open(filePath, FileMode.Open))
{
var binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
return (T)binaryFormatter.Deserialize(stream);
}
}
XML
Requires the System.Xml assembly to be included in your project.
/// <summary>
/// Writes the given object instance to an XML file.
/// <para>Only Public properties and variables will be written to the file. These can be any type though, even other classes.</para>
/// <para>If there are public properties/variables that you do not want written to the file, decorate them with the [XmlIgnore] attribute.</para>
/// <para>Object type must have a parameterless constructor.</para>
/// </summary>
/// <typeparam name="T">The type of object being written to the file.</typeparam>
/// <param name="filePath">The file path to write the object instance to.</param>
/// <param name="objectToWrite">The object instance to write to the file.</param>
/// <param name="append">If false the file will be overwritten if it already exists. If true the contents will be appended to the file.</param>
public static void WriteToXmlFile<T>(string filePath, T objectToWrite, bool append = false) where T : new()
{
TextWriter writer = null;
try
{
var serializer = new XmlSerializer(typeof(T));
writer = new StreamWriter(filePath, append);
serializer.Serialize(writer, objectToWrite);
}
finally
{
if (writer != null)
writer.Close();
}
}
/// <summary>
/// Reads an object instance from an XML file.
/// <para>Object type must have a parameterless constructor.</para>
/// </summary>
/// <typeparam name="T">The type of object to read from the file.</typeparam>
/// <param name="filePath">The file path to read the object instance from.</param>
/// <returns>Returns a new instance of the object read from the XML file.</returns>
public static T ReadFromXmlFile<T>(string filePath) where T : new()
{
TextReader reader = null;
try
{
var serializer = new XmlSerializer(typeof(T));
reader = new StreamReader(filePath);
return (T)serializer.Deserialize(reader);
}
finally
{
if (reader != null)
reader.Close();
}
}
Json
You must include a reference to Newtonsoft.Json assembly, which can be obtained from the Json.NET NuGet Package.
/// <summary>
/// Writes the given object instance to a Json file.
/// <para>Object type must have a parameterless constructor.</para>
/// <para>Only Public properties and variables will be written to the file. These can be any type though, even other classes.</para>
/// <para>If there are public properties/variables that you do not want written to the file, decorate them with the [JsonIgnore] attribute.</para>
/// </summary>
/// <typeparam name="T">The type of object being written to the file.</typeparam>
/// <param name="filePath">The file path to write the object instance to.</param>
/// <param name="objectToWrite">The object instance to write to the file.</param>
/// <param name="append">If false the file will be overwritten if it already exists. If true the contents will be appended to the file.</param>
public static void WriteToJsonFile<T>(string filePath, T objectToWrite, bool append = false) where T : new()
{
TextWriter writer = null;
try
{
var contentsToWriteToFile = JsonConvert.SerializeObject(objectToWrite);
writer = new StreamWriter(filePath, append);
writer.Write(contentsToWriteToFile);
}
finally
{
if (writer != null)
writer.Close();
}
}
/// <summary>
/// Reads an object instance from an Json file.
/// <para>Object type must have a parameterless constructor.</para>
/// </summary>
/// <typeparam name="T">The type of object to read from the file.</typeparam>
/// <param name="filePath">The file path to read the object instance from.</param>
/// <returns>Returns a new instance of the object read from the Json file.</returns>
public static T ReadFromJsonFile<T>(string filePath) where T : new()
{
TextReader reader = null;
try
{
reader = new StreamReader(filePath);
var fileContents = reader.ReadToEnd();
return JsonConvert.DeserializeObject<T>(fileContents);
}
finally
{
if (reader != null)
reader.Close();
}
}
Example
// Write the list of salesman objects to file.
WriteToXmlFile<List<salesman>>("C:\salesmen.txt", salesmanList);
// Read the list of salesman objects from the file back into a variable.
List<salesman> salesmanList = ReadFromXmlFile<List<salesman>>("C:\salesmen.txt");
If you want to use JSON then using Json.NET is usually the best way to go.
If for some reason you are unable to use Json.NET you can use the built in JSON support found in .NET.
You will need to include the following using statement and add a reference for System.Web.Extentsions.
using System.Web.Script.Serialization;
Then you would use these to Serialize and Deserialize your object.
//Deserialize JSON to your Object
YourObject obj = new JavaScriptSerializer().Deserialize<YourObject>("File Contents");
//Serialize your object to JSON
string sJSON = new JavaScriptSerializer().Serialize(YourObject);
https://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer_methods(v=vs.110).aspx
If you want xml serialization, you can use the built-in serializer. To achieve this, add [Serializable] flag to the class:
[Serializable()]
class salesman
{
public string name, address, email;
public int sales;
}
Then, you could override the "ToString()" method which converts the data into xml string:
public override string ToString()
{
string sData = "";
using (MemoryStream oStream = new MemoryStream())
{
XmlSerializer oSerializer = new XmlSerializer(this.GetType());
oSerializer.Serialize(oStream, this);
oStream.Position = 0;
sData = Encoding.UTF8.GetString(oStream.ToArray());
}
return sData;
}
Then just create a method that writes this.ToString() into a file.
UPDATE
The mentioned above will serialize single entry as xml. If you need the whole list to be serialized, the idea would be a bit different. In this case you'd employ the fact that lists are serializable if their contents are serializable and use the serialization in some outer class.
Example code:
[Serializable()]
class salesman
{
public string name, address, email;
public int sales;
}
class salesmenCollection
{
List<salesman> salesmanList;
public void SaveTo(string path){
System.IO.File.WriteAllText (path, this.ToString());
}
public override string ToString()
{
string sData = "";
using (MemoryStream oStream = new MemoryStream())
{
XmlSerializer oSerializer = new XmlSerializer(this.GetType());
oSerializer.Serialize(oStream, this);
oStream.Position = 0;
sData = Encoding.UTF8.GetString(oStream.ToArray());
}
return sData;
}
}