StreamWriter to Reference Type - c#

Persisting a reference type with the StreamWriter is easy enough. And retrieving this data back into a string is easy as well, with the StreamReader.
But how can i convert the string the StreamReader returns into my custom reference type ?

Persisting reference types (objects of classes) is called serialization. Reverse process is called deserialization. Both can be done easily in .net using XmlSerializer:
XmlSerializer serializer = new XmlSerializer(typeof(OrderedItem));
OrderedItem item = new OrderedItem();
//do stuff
using (StreamWriter sw = new StreamWriter(filename))
serializer.Serialize(sw, item);
reverse
XmlSerializer serializer = new XmlSerializer(typeof(OrderedItem));
OrderedItem item = null;
using (StreamReader sr = new StreamReader(filename))
item = (OrderedItem)serializer.Deserialize(sr);

Related

Deserialize object one by one from file .Net

I'm trying to deserialize a list of heavy objects from a json file. I do not want to deserialize it the classic way, like directly to a list, because it will expose me to an OutOfMemory exception. So I'm looking for a way to handle object one by one to store them one by one in the database and be memory safe.
I already handle the serialization and it's working well, but I'm facing some difficulties for deserialization.
Any idea ?
Thanks in advance
// Serialization
using (var FileStream = new FileStream(DirPath + "/TPV.Json", FileMode.Create))
{
using (var sw = new StreamWriter(FileStream))
{
using (var jw = new JsonTextWriter(sw))
{
jw.WriteStartArray();
using (var _Database = new InspectionBatimentsDataContext(TheBrain.DBClient.ConnectionString))
{
foreach (var TPVId in TPVIds)
{
var pic = (from p in _Database.TPV
where Operators.ConditionalCompareObjectEqual(p.Release, TPVId.Release, false) & Operators.ConditionalCompareObjectEqual(p.InterventionId, TPVId.InterventionId, false)
select p).FirstOrDefault;
var ser = new JsonSerializer();
ser.Serialize(jw, pic);
jw.Flush();
}
}
jw.WriteEndArray();
}
}
}
I finnaly found a way to do it by using custom separator beetween each object during serialization. Then for deserialization, I simply read the json file as string until I find my custom separator and I deserialise readed string, all in a loop. It's not the perfect answer because I'm breaking json format in my files, but it's not a constraint in my case.

Exception when writing data with CsvHelper

I'm trying to write data to a CSV-file using CsvHelper. However, I always get the following exception:
CsvHelper.Configuration.ConfigurationException: "Types that inherit
IEnumerable cannot be auto mapped. Did you accidentally call GetRecord
or WriteRecord which acts on a single record instead of calling
GetRecords or WriteRecords which acts on a list of records?"
This is my code (C#):
TextWriter outfile = new StreamWriter("blatest.csv");
List<string> test = new List<string>
{
"hello",
"world"
};
CsvWriter csv = new CsvWriter(outfile);
csv.WriteRecords(test);
I would like to write a List<string> or (ideally) a List<Dictionary<string, string>> to CSV. What would be the correct code for this? And how can I set the header row?
Any help is appreciated. I really can't wrap my head around this.
For the error, it is because string implements IEnumerable (because it is char[]). Generally using WriteRecords you pass in an IEnumerable of custom objects.
You could try another way (Example)
using(var stream = new MemoryStream())
using(var reader = new StreamReader(stream))
using(var writer = new StreamWriter(stream))
using(var csvWriter = new CsvHelper.CsvWriter(writer))
{
//csvWriter.Configuration.HasHeaderRecord = false;
foreach( var s in test)
{
csvWriter.WriteField(s);
}
writer.Flush();
stream.Position = 0;
reader.ReadToEnd(); //dump it where you want
}

Save file - xmlSerializer

I'm creating a method to serialize a file using this code:
public void Save(Object file, Type type, String path)
{
// Create a new Serializer
XmlSerializer serializer = new XmlSerializer(typeof(type));
// Create a new StreamWriter
StreamWriter writer = new StreamWriter(#path);
// Serialize the file
serializer.Serialize(writer, file);
// Close the writer
writer.Close();
}
But Visual Studio tells me this when I attempt to build:
"Error 1 The type or namespace name 'type' could not be found (are you missing a using directive or an assembly reference?) c:\users\erik\documents\visual studio 2013\Projects\FileSerializer\FileSerializer\Class1.cs 16 65 FileSerializer
"
Why is this?
**EDIT*
New code that works:
public void Save(Object file, String path, Type type)
{
// Create a new Serializer
XmlSerializer serializer = new XmlSerializer(type);
// Create a new StreamWriter
TextWriter writer = new StreamWriter(path);
// Serialize the file
serializer.Serialize(writer, file);
// Close the writer
writer.Close();
}
public object Read(String path, Type type)
{
// Create a new serializer
XmlSerializer serializer = new XmlSerializer(type);
// Create a StreamReader
TextReader reader = new StreamReader(path);
// Deserialize the file
Object file;
file = (Object)serializer.Deserialize(reader);
// Close the reader
reader.Close();
// Return the object
return file;
}
read by calling:
myClass newClass = (myClass)Read(file, type);
Save by calling:
Save(object, path, type);
Thanks!
Erik
Your error is in new XmlSerializer(typeof(type));. You don't need typeof. new XmlSerializer(type); is enough.
Since you serialize file object (and its type can be determined in the function) you don't have to pass its type. So your code can be re-written as
public void Save<T>(T file, String path)
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
using (StreamWriter writer = new StreamWriter(path))
{
serializer.Serialize(writer, file);
}
}
var serializer = new System.Xml.Serialization.XmlSerializer(type);
instead of
XmlSerializer serializer = new XmlSerializer(typeof(type));
XmlSerializer takes a Type parameter. type is already of type Type, so you don't need to call typeof() on it. typeof() is only needed when you're putting a class name or generic parameter inside the brackets.

How to serialize an object to XML that can be stored SQL database field of type XML

I have a c# web MVC application.
I wish to serialize my model object to an XML to be stored in a SQL database field of type XML?
I was able to serialize to a file using:
var writer = new System.Xml.Serialization.XmlSerializer(typeof(car));
var file = new System.IO.StreamWriter(#"C:\car.xml");
Writer.Serialize(file, car);
file.Close();
How can I modify this code to serialize to type XML of which I can then store into my SQL table and field XML type
You can use StringWriter with XmlWriter to produce the xml string then save to your database
string xmlResult = string.Empty;
var xmlSerializer = new XmlSerializer(typeof(car));
using (var stringWriter = new StringWriter())
{
using (var xmlWriter = XmlWriter.Create(stringWriter))
{
xmlSerializer.Serialize(xmlWriter, car);
}
xmlResult = stringWriter.ToString();
}
// save xmlResult to DB

How to make custom xml serialization

I have tried to serialize data using XmlSerializer. I have found very a useful post: XML Serializable Generic Dictionary.
But in fact I need to put the result of serialization not in file but in a string variable, how can I do this?
Instead of using some StreamWriter which points to file you can use StringWriter class.
using (StringWriter writer = new StringWriter())
{
XmlSerializer serializer = new XmlSerializer(typeof (YourType));
serializer.Serialize(writer, yourObject);
}
XmlWriter.Create() function has one overload which takes StringBuilder, try using it.

Categories

Resources