C# Serialization, Deserialization of an array of objects - c#

I've got this code.
const int maxbooks = 5;
Book[] booklist = new Book[maxbooks];
FileStream fs = File.Open(#"books.txt", FileMode.Open, FileAccess.Read);
SoapFormatter sf = new SoapFormatter();
try
{
// something here, deserializing file and assigning to the array
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
fs.Close();
}
I've figured out (or at least, I THINK I've figured out) how to serialize the original array of objects in a separate program. I'm now looking to de serialize that, and create a new array with the de serialized data. Just for reference, here's the other file where I serialized the original array
Book firstbook = new Book("Jimbob", "Jimbob book", "first edition", "Jimbob publishing", "1991");
Book secondbook = new Book("Greg", "Greg book", "third edition", "Unholy publishing", "2010");
Book thirdbook = new Book("Pingu", "Pingu book", "tenth edition", "Antarctic publishing", "1897");
Book fourthbook = new Book("Patrick", "Patrick book", "seventh edition", "underwater publishing", "1991");
Book fifthbook = new Book("Sally", "Sally book", "first edition", "Wowpublishing", "2015");
const int maxbooks = 5;
Book[] booklist = new Book[maxbooks];
booklist[0] = firstbook;
booklist[1] = secondbook;
booklist[2] = thirdbook;
booklist[3] = fourthbook;
booklist[4] = fifthbook;
// writing to a file
FileStream fs = File.Open(#"books.txt", FileMode.Create, FileAccess.Write);
SoapFormatter sf = new SoapFormatter();
int bookindex = 0;
try
{
while (bookindex < maxbooks)
{
sf.Serialize(fs, booklist[bookindex]);
bookindex += 1;
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
fs.Close();
}
Using SOAP serialization for the moment with this. Any help will be appreciated.

Serialise the array itself rather than per item. With your serialiser routine you are creating many serialisation chunks that are not valid together appended in a file.

Use the XMLSerializer
For e.g.
Serialize like this:
private async Task SaveSettings(Settings settings)
{
var folder = Windows.Storage.ApplicationData.Current.LocalFolder;
var options = Windows.Storage.CreationCollisionOption.ReplaceExisting;
var file = await folder.CreateFileAsync("Settings.XML", options);
try
{
XmlSerializer SerializerObj = new XmlSerializer(typeof(Settings));
SerializerObj.Serialize(await file.OpenStreamForWriteAsync(), settings);
}
catch
{
// handle any kind of exceptions
}
}
Deserialize like this:
private async Task<Settings> LoadSettings()
{
Settings settings = new Settings();
var folder = Windows.Storage.ApplicationData.Current.LocalFolder;
try
{
var file = await folder.GetFileAsync("Settings.XML");
XmlSerializer SerializerObj = new XmlSerializer(typeof(Settings));
settings = SerializerObj.Deserialize(await file.OpenStreamForReadAsync()) as Settings;
}
catch (Exception ex)
{
// handle any kind of exceptions
}
return settings;
}
This example serializes an object called Settings. You can change it to serialize your array of objects.
This is from a windows 8 app so you may need to adapt it slightly.

Related

What is contaminating this switch statement?

I have a system which is doing following,
Upload documents to SharePoint
Event receiver will add job to DB, Create a folder for job in Document Conversion Directory
A directory watcher will trigger Document Conversion windows service
Windows service will get batch of 10 jobs from DB (using main thread)
On start Windows service creates X number of threads based on processor's cores (using Parallel For)
Then creates worker thread with timeouts for every db jobs (this is different from parallel For threads)
and it carries on...
Oh while converting... in worker threads.. we are calling ActiveDirectory, logging to DB (Read, Write) and uploading document back to SharePoint
I manage to break it... if I upload a password protected document... and soon after upload a powerpoint document, powerpoint document throws password incorrect exception etc..
but if there's gap inbetween both documents even 60 seconds, it all works fine which means powerpoint document does converts to PDF.
Following is the code but I had to trim unnecessary parts out of it,
Here is the main class where things start from,
Parallel.For(0, noOfThreadsToRunOnPDFServer, new ParallelOptions { MaxDegreeOfParallelism = noOfThreadsToRunOnPDFServer },
i =>
{
this.docConvService.ProcessDocuments(i);
});
Then the conversion is happening here...
using System;
using System.IO;
using System.Runtime.ExceptionServices;
using System.Threading;
namespace PDFService
{
public class AsposePDFConverter : IPDFConverter
{
private IDocConversionSettings settings;
private ExceptionDispatchInfo conversionException = null;
public enum SupportedExtensions
{
Doc,
Docx,
Xls,
Xlsx,
Pdf,
Pps,
Ppsx,
Ppt,
Pptx,
Txt,
Html,
Mhtml,
Xhtml,
Msg,
Eml,
Emlx,
One,
Vsd,
Vsdx,
Vss,
Vssx
}
public AsposePDFConverter(IDocConversionSettings settings)
{
this.settings = settings;
}
private void SyncThreadStartWithTimeout(ThreadStart threadStart, TimeSpan timeout)
{
Thread workerThread = new Thread(threadStart);
workerThread.Start();
bool finished = workerThread.Join(timeout);
if (!finished)
{
workerThread.Abort();
throw new ConversionTimeoutException("PDF Conversion exceeded timeout value");
}
}
public MemoryStream ConvertToPDF(string documentName, Stream docContent, double timeoutMS)
{
this.conversionException = null;
MemoryStream outStream = null;
MemoryStream inStream = new MemoryStream();
docContent.CopyTo(inStream);
inStream.Seek(0, SeekOrigin.Begin);
SupportedExtensions documentExtension;
string szExtension = Path.GetExtension(documentName).TrimStart('.');
if (Enum.TryParse(szExtension, true, out documentExtension))
{
switch (documentExtension)
{
case SupportedExtensions.Doc:
case SupportedExtensions.Docx:
case SupportedExtensions.Txt:
case SupportedExtensions.Html:
case SupportedExtensions.Mhtml:
case SupportedExtensions.Xhtml:
SyncThreadStartWithTimeout(
() => { outStream = ConvertWordsToPDF(inStream); },
TimeSpan.FromMilliseconds(timeoutMS));
break;
case SupportedExtensions.Pps:
case SupportedExtensions.Ppsx:
case SupportedExtensions.Ppt:
case SupportedExtensions.Pptx:
SyncThreadStartWithTimeout(
() => { outStream = ConvertSlidesToPDF(inStream); },
TimeSpan.FromMilliseconds(timeoutMS));
break;
}
// Conversion happens on sub-threads so they can time out, if they throw an exception, throw it from this thread
if (this.conversionException != null)
this.conversionException.Throw();
return outStream;
}
else
{
throw new FormatNotSupportedException("Document type is not supported");
}
}
private MemoryStream ConvertWordsToPDF(Stream docContent)
{
try
{
Aspose.Words.License lic = new Aspose.Words.License();
lic.SetLicense(this.settings.AsposeLicensePath);
Aspose.Words.Document doc = new Aspose.Words.Document(docContent);
MemoryStream stream = new MemoryStream();
doc.Save(stream, Aspose.Words.SaveFormat.Pdf);
return stream;
}
catch (Exception ex)
{
this.conversionException = ExceptionDispatchInfo.Capture(ex);
return null;
}
}
private MemoryStream ConvertSlidesToPDF(Stream docContent)
{
try
{
Aspose.Slides.License lic = new Aspose.Slides.License();
lic.SetLicense(this.settings.AsposeLicensePath);
using (Aspose.Slides.Presentation presentation = new Aspose.Slides.Presentation(docContent))
{
MemoryStream stream = new MemoryStream();
presentation.Save(stream, Aspose.Slides.Export.SaveFormat.Pdf);
return stream;
}
}
catch (Exception ex)
{
this.conversionException = ExceptionDispatchInfo.Capture(ex);
return null;
}
}
}
}
Error is,
Error during Document PDF Conversion. Details are: PDFConversionID:
6061, DocumentName: powerpoint.ppsx, WebURL: REMOVED, UploadedBy:
REMOVED, ConversionDuration: 00:01:06.3072410
Aspose.Words.IncorrectPasswordException: The document password is
incorrect. at Aspose.Words.Document. (Stream , LoadOptions )
at Aspose.Words.Document. (Stream , LoadOptions ) at
DocumentPDFConversionService.AsposePDFConverter.ConvertWordsToPDF(Stream
docContent) in...
As you can see there is something very fishy going on
You are using the same instance of this.docConvService in multiple threads, so your conversionException property is probably written by the password-protected doc while your other document is processing. You should instanciate a new instance of your AsposePDFConverter, or change the way you return exceptions, e.g. in a result-object returned by ConvertToPDF, that contains a MemoryStream and your error.
Seperate instance for each request :
Parallel.For(0, noOfThreadsToRunOnPDFServer, new ParallelOptions { MaxDegreeOfParallelism = noOfThreadsToRunOnPDFServer },
i =>
{
new AsposePdfConverter(settings).ProcessDocuments(i);
});
Returning a result-object :
public ConversionResult ConvertToPDF(string documentName, Stream docContent, double timeoutMS)
{
/** Your code **/
return new ConversionResult()
{
MemoryStream = memoryStream,
ConversionException = conversionException
};
}
class ConversionResult {
MemoryStream MemoryStream {get;set;}
ExceptionDispatchInfo ConversionException {get;set;}
}

How do I write raw data from any data type to a file with C#?

I'm writing a Windows app in C#. I have a custom data type that I need to write as raw data to a binary file (not text/string based), and then open that file later back into that custom data type.
For example:
Matrix<float> dbDescs = ConcatDescriptors(dbDescsList);
I need to save dbDescs to file blah.xyz and then restore it as Matrix<float> later. Anyone have any examples? Thanks!
As I've mentioned, the options are overwhelming and this question comes with a ton of opinions as far as which one is the best. With that being said, BinaryFormatter could prove to be useful here as it serializes and deserializes object (along with graphs of connected objects) in binary.
Here's the MSDN link that explains the usage: https://msdn.microsoft.com/en-us/library/system.runtime.serialization.formatters.binary.binaryformatter(v=vs.110).aspx
Just in case that link fails down the line and because I'm too lazy to provide my own example, here's an example from MSDN:
using System;
using System.IO;
using System.Collections;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
public class App
{
[STAThread]
static void Main()
{
Serialize();
Deserialize();
}
static void Serialize()
{
// Create a hashtable of values that will eventually be serialized.
Hashtable addresses = new Hashtable();
addresses.Add("Jeff", "123 Main Street, Redmond, WA 98052");
addresses.Add("Fred", "987 Pine Road, Phila., PA 19116");
addresses.Add("Mary", "PO Box 112233, Palo Alto, CA 94301");
// To serialize the hashtable and its key/value pairs,
// you must first open a stream for writing.
// In this case, use a file stream.
FileStream fs = new FileStream("DataFile.dat", FileMode.Create);
// Construct a BinaryFormatter and use it to serialize the data to the stream.
BinaryFormatter formatter = new BinaryFormatter();
try
{
formatter.Serialize(fs, addresses);
}
catch (SerializationException e)
{
Console.WriteLine("Failed to serialize. Reason: " + e.Message);
throw;
}
finally
{
fs.Close();
}
}
static void Deserialize()
{
// Declare the hashtable reference.
Hashtable addresses = null;
// Open the file containing the data that you want to deserialize.
FileStream fs = new FileStream("DataFile.dat", FileMode.Open);
try
{
BinaryFormatter formatter = new BinaryFormatter();
// Deserialize the hashtable from the file and
// assign the reference to the local variable.
addresses = (Hashtable) formatter.Deserialize(fs);
}
catch (SerializationException e)
{
Console.WriteLine("Failed to deserialize. Reason: " + e.Message);
throw;
}
finally
{
fs.Close();
}
// To prove that the table deserialized correctly,
// display the key/value pairs.
foreach (DictionaryEntry de in addresses)
{
Console.WriteLine("{0} lives at {1}.", de.Key, de.Value);
}
}
}
Consider the Json.Net package (you can download it to your project via Nuget; the better way, or get it directly from their website).
JSON is just a string (text) that holds values for complex objects. It allows you to turn many (not all) objects into savable files easily which then can be pulled back. To serialize into JSON with JSON.net:
Product product = new Product();
product.Name = "Apple";
product.Expiry = new DateTime(2008, 12, 28);
product.Sizes = new string[] { "Small" };
string json = JsonConvert.SerializeObject(product);
And then to deserialize:
var product = JsonConvert.DeserializeObject(json);
To write the json to a file:
using (StreamWriter writer = new StreamWriter(#"C:/file.txt"))
{
writer.WriteLine(json);
}
I am not a Web Developer so I am not sure that JSON is Binary. Isnt it still text based? So here is what I know is a Binary Answer. Hope this Helps!
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BinarySerializerSample
{
class Program
{
public static void WriteValues(string fName, double[] vals)
{
using (BinaryWriter writer = new BinaryWriter(File.Open(fName, FileMode.Create)))
{
int len = vals.Length;
for (int i = 0; i < len; i++)
writer.Write(vals[i]);
}
}
public static double[] ReadValues(string fName, int len)
{
double [] vals = new double[len];
using (BinaryReader reader = new BinaryReader(File.Open(fName, FileMode.Open)))
{
for (int i = 0; i < len; i++)
vals[i] = reader.ReadDouble();
}
return vals;
}
static void Main(string[] args)
{
const double MAX_TO_VARY = 100.0;
const int NUM_ITEMS = 100;
const string FILE_NAME = "dblToTestx.bin";
double[] dblToWrite = new double[NUM_ITEMS];
Random r = new Random();
for (int i = 0; i < NUM_ITEMS; i++)
dblToWrite[i] = r.NextDouble() * MAX_TO_VARY;
WriteValues(FILE_NAME, dblToWrite);
double[] dblToRead ;
dblToRead = ReadValues(FILE_NAME, NUM_ITEMS);
int j = 0;
bool areEqual = true;
while (areEqual && j < NUM_ITEMS)
{
areEqual = dblToRead[j] == dblToWrite[j];
++j;
}
if (areEqual)
Console.WriteLine("Test Passed: Press any Key to Exit");
else
Console.WriteLine("Test Failed: Press any Key to Exit");
Console.Read();
}
}
}

error in XML document. Unexpected XML declaration. XML declaration must be the first node in the document

There is an error in XML document (8, 20). Inner 1: Unexpected XML declaration. The XML declaration must be the first node in the document, and no white space characters are allowed to appear before it.
OK, I understand this error.
How I get it, however, is what perplexes me.
I create the document with Microsoft's Serialize tool. Then, I turn around and attempt to read it back, again, using Microsoft's Deserialize tool.
I am not in control of writing the XML file in the correct format - that I can see.
Here is the single routine I use to read and write.
private string xmlPath = System.Web.Hosting.HostingEnvironment.MapPath(WebConfigurationManager.AppSettings["DATA_XML"]);
private object objLock = new Object();
public string ErrorMessage { get; set; }
public StoredMsgs Operation(string from, string message, FileAccess access) {
StoredMsgs list = null;
lock (objLock) {
ErrorMessage = null;
try {
if (!File.Exists(xmlPath)) {
var root = new XmlRootAttribute(rootName);
var serializer = new XmlSerializer(typeof(StoredMsgs), root);
if (String.IsNullOrEmpty(message)) {
from = "Code Window";
message = "Created File";
}
var item = new StoredMsg() {
From = from,
Date = DateTime.Now.ToString("s"),
Message = message
};
using (var stream = File.Create(xmlPath)) {
list = new StoredMsgs();
list.Add(item);
serializer.Serialize(stream, list);
}
} else {
var root = new XmlRootAttribute("MessageHistory");
var serializer = new XmlSerializer(typeof(StoredMsgs), root);
var item = new StoredMsg() {
From = from,
Date = DateTime.Now.ToString("s"),
Message = message
};
using (var stream = File.Open(xmlPath, FileMode.Open, FileAccess.ReadWrite)) {
list = (StoredMsgs)serializer.Deserialize(stream);
if ((access == FileAccess.ReadWrite) || (access == FileAccess.Write)) {
list.Add(item);
serializer.Serialize(stream, list);
}
}
}
} catch (Exception error) {
var sb = new StringBuilder();
int index = 0;
sb.AppendLine(String.Format("Top Level Error: <b>{0}</b>", error.Message));
var err = error.InnerException;
while (err != null) {
index++;
sb.AppendLine(String.Format("\tInner {0}: {1}", index, err.Message));
err = err.InnerException;
}
ErrorMessage = sb.ToString();
}
}
return list;
}
Is something wrong with my routine? If Microsoft write the file, it seems to me that it should be able to read it back.
It should be generic enough for anyone to use.
Here is my StoredMsg class:
[Serializable()]
[XmlType("StoredMessage")]
public class StoredMessage {
public StoredMessage() {
}
[XmlElement("From")]
public string From { get; set; }
[XmlElement("Date")]
public string Date { get; set; }
[XmlElement("Message")]
public string Message { get; set; }
}
[Serializable()]
[XmlRoot("MessageHistory")]
public class MessageHistory : List<StoredMessage> {
}
The file it generates doesn't look to me like it has any issues.
I saw the solution here:
Error: The XML declaration must be the first node in the document
But, in that case, it seems someone already had an XML document they wanted to read. They just had to fix it.
I have an XML document created my Microsoft, so it should be read back in by Microsoft.
The problem is that you are adding to the file. You deserialize, then re-serialize to the same stream without rewinding and resizing to zero. This gives you multiple root elements:
<?xml version="1.0"?>
<StoredMessage>
</StoredMessage
<?xml version="1.0"?>
<StoredMessage>
</StoredMessage
Multiple root elements, and multiple XML declarations, are invalid according to the XML standard, thus the .NET XML parser throws an exception in this situation by default.
For possible solutions, see XML Error: There are multiple root elements, which suggests you either:
Enclose your list of StoredMessage elements in some synthetic outer element, e.g. StoredMessageList.
This would require you to load the list of messages from the file, add the new message, and then truncate the file and re-serialize the entire list when adding a single item. Thus the performance may be worse than in your current approach, but the XML will be valid.
When deserializing a file containing concatenated root elements, create an XML writer using XmlReaderSettings.ConformanceLevel = ConformanceLevel.Fragment and iteratively walk through the concatenated root node(s) and deserialize each one individually as shown, e.g., here. Using ConformanceLevel.Fragment allows the reader to parse streams with multiple root elements (although multiple XML declarations will still cause an error to be thrown).
Later, when adding a new element to the end of the file using XmlSerializer, seek to the end of the file and serialize using an XML writer returned from XmlWriter.Create(TextWriter, XmlWriterSettings)
with XmlWriterSettings.OmitXmlDeclaration = true. This prevents output of multiple XML declarations as explained here.
For option #2, your Operation would look something like the following:
private string xmlPath = System.Web.Hosting.HostingEnvironment.MapPath(WebConfigurationManager.AppSettings["DATA_XML"]);
private object objLock = new Object();
public string ErrorMessage { get; set; }
const string rootName = "MessageHistory";
static readonly XmlSerializer serializer = new XmlSerializer(typeof(StoredMessage), new XmlRootAttribute(rootName));
public MessageHistory Operation(string from, string message, FileAccess access)
{
var list = new MessageHistory();
lock (objLock)
{
ErrorMessage = null;
try
{
using (var file = File.Open(xmlPath, FileMode.OpenOrCreate))
{
list.AddRange(XmlSerializerHelper.ReadObjects<StoredMessage>(file, false, serializer));
if (list.Count == 0 && String.IsNullOrEmpty(message))
{
from = "Code Window";
message = "Created File";
}
var item = new StoredMessage()
{
From = from,
Date = DateTime.Now.ToString("s"),
Message = message
};
if ((access == FileAccess.ReadWrite) || (access == FileAccess.Write))
{
file.Seek(0, SeekOrigin.End);
var writerSettings = new XmlWriterSettings
{
OmitXmlDeclaration = true,
Indent = true, // Optional; remove if compact XML is desired.
};
using (var textWriter = new StreamWriter(file))
{
if (list.Count > 0)
textWriter.WriteLine();
using (var xmlWriter = XmlWriter.Create(textWriter, writerSettings))
{
serializer.Serialize(xmlWriter, item);
}
}
}
list.Add(item);
}
}
catch (Exception error)
{
var sb = new StringBuilder();
int index = 0;
sb.AppendLine(String.Format("Top Level Error: <b>{0}</b>", error.Message));
var err = error.InnerException;
while (err != null)
{
index++;
sb.AppendLine(String.Format("\tInner {0}: {1}", index, err.Message));
err = err.InnerException;
}
ErrorMessage = sb.ToString();
}
}
return list;
}
Using the following extension method adapted from Read nodes of a xml file in C#:
public partial class XmlSerializerHelper
{
public static List<T> ReadObjects<T>(Stream stream, bool closeInput = true, XmlSerializer serializer = null)
{
var list = new List<T>();
serializer = serializer ?? new XmlSerializer(typeof(T));
var settings = new XmlReaderSettings
{
ConformanceLevel = ConformanceLevel.Fragment,
CloseInput = closeInput,
};
using (var xmlTextReader = XmlReader.Create(stream, settings))
{
while (xmlTextReader.Read())
{ // Skip whitespace
if (xmlTextReader.NodeType == XmlNodeType.Element)
{
using (var subReader = xmlTextReader.ReadSubtree())
{
var logEvent = (T)serializer.Deserialize(subReader);
list.Add(logEvent);
}
}
}
}
return list;
}
}
Note that if you are going to create an XmlSerializer using a custom XmlRootAttribute, you must cache the serializer to avoid a memory leak.
Sample fiddle.

Attempting to deserialize an empty stream?

I'm building a program for my school's swim lesson organization, and I'm saving the data using XML serialization, but I keep getting an error every time I try to deserialize the data, it says "Runtime Error: Attempting to Deserialize an Empty Stream."
Here is my code to deserialize the file and put it into a window.
public StudentProfile()
{
InitializeComponent();
using (var file = File.Open(FindStudent.studentName + ".xml", FileMode.OpenOrCreate))
{
var bformatter = new BinaryFormatter();
var mp = (Person)bformatter.Deserialize(file);
file.Close();
nameBox.Text += mp.studentName;
parentBox.Text += mp.parentName;
yearBox.Text += mp.year;
semesterBox.Text += mp.semester;
sessionBox.Text += mp.session;
ageGroupBox.Text += mp.ageGroup;
sessionTimeBox.Text += mp.sessionTime;
levelBox.Text += mp.level;
paymentTypeBox.Text += mp.paymentType;
amountBox.Text += mp.amount;
checkNumberBox.Text += mp.checkNumber;
datePaidBox.Text += mp.datePaid;
}
}
I've tried some solutions on here, BinaryFormatter: SerializationException, but it still doesn't work. Can you guys help me?
Edit: I solved my error, using a different method, here is the code I ended up using to deserialize it. If anyone wants the serialization code, then I'll give it
Stream file = File.Open(#"C:\Swimmers\" + FindStudent.studentName + ".xml", FileMode.Open);
BinaryFormatter bformatter = new BinaryFormatter();
Person mp = (Person)bformatter.Deserialize(file);
file.Close();
nameBox.Text += mp.studentName;
parentBox.Text += mp.parentName;
yearBox.Text += mp.year;
semesterBox.Text += mp.semester;
sessionBox.Text += mp.session;
ageGroupBox.Text += mp.ageGroup;
sessionTimeBox.Text += mp.sessionTime;
levelBox.Text += mp.level;
paymentTypeBox.Text += mp.paymentType;
amountBox.Text += mp.amount;
checkNumberBox.Text += mp.checkNumber;
datePaidBox.Text += mp.datePaid;
}
With a FileMode of OpenOrCreate, if the file hasn't existed yet, it creates the file with no content, and thus would fail deserialization. It would be better to use:
if (File.Exists(FindStudent.StudentName + ".xml"))
{
//Serialization logic
}
else
{
//default logic; create the file but don't deserialize
//expect the UI to be loaded blank
}
That is probably the error you are experiencing, because you are deserializing a newly created blank file.
I strongly recommend you System.Runtime.Serialization Namespace, from System.Runtime.Serialization.dll. It provides serializers implementation such as XML and JSON.
The following example uses the DataContractSerializer.
[DataContract]
public class Student
{
[DataMember]
public string Name { get; set; }
[DataMember]
public int Age { get; set; }
public void Save(string filePath)
{
using (var fs = File.Open(filePath, FileMode.Create))
{
DataContractSerializer serializer = new DataContractSerializer(typeof (Student));
serializer.WriteObject(fs, this);
}
}
public static Student Load(string filePath)
{
Student result = null; //or default result
try
{
using (var fs = File.OpenRead(filePath))
{
DataContractSerializer serializer = new DataContractSerializer(typeof (Student));
result = serializer.ReadObject(fs) as Student;
}
}
catch (Exception)
{
}
return result;
}
}
Usage example:
...
var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "student1.xml");
var student = new Student
{
Name = "Student1",
Age = 10
};
student.Save(filePath);
var studentFromFile = Student.Load(filePath);
...
I hope it helps.

Dataset won't update image to database

I'm trying to insert an image into a SQL Server database, it get into the dataset but when the save method is called, SQL Server doesn't change.
public void AddImage(OpenFileDialog openFileDialog1, List<Movie> movieList)
{
byte[] movieCover = null;
FileStream movieStream = new FileStream(openFileDialog1.FileName, FileMode.Open, FileAccess.Read);
BinaryReader movieReader = new BinaryReader(movieStream);
movieCover = movieReader.ReadBytes((int)movieStream.Length);
var Starwars = new object[2];
Starwars[0] = "Star Wars: Episode I - The Phantom Menace";
Starwars[1] = "1999";
var found = _movieSet.Tables["Movie"].Rows.Find(Starwars);
if (found != null)
{
found.SetField("Cover", movieCover);
var movieListFound = movieList.Find(x => x.Name == Starwars[0]);
}
else
MessageBox.Show("Movie Not Found");
}
The save method
public void Save()
{
var movieConnection = new SqlConnection();
try
{
movieConnection = new SqlConnection(Properties.Settings.Default.moviesConnectionString);
movieConnection.Open();
_movieAdapter.Update(_movieSet, "Movie");
movieConnection.Close();
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
finally
{
movieConnection.Dispose();
}
}
Adding new rows works but any sort of change to the actual data set is not updated when the save method is called, not just image but if I change the table data with data visualizer in debugging.
Yet again I answer my own question a day later, wish I got better responses but I suppose my information must not be the best or something.
I needed to call the Save() method during the Addimage method.
public void AddImage(OpenFileDialog openFileDialog1, List<Movie> movieList)
{
byte[] movieCover = null;
FileStream movieStream = new FileStream(openFileDialog1.FileName, FileMode.Open, FileAccess.Read);
BinaryReader movieReader = new BinaryReader(movieStream);
movieCover = movieReader.ReadBytes((int)movieStream.Length);
var Starwars = new object[2];
Starwars[0] = "Star Wars: Episode I - The Phantom Menace";
Starwars[1] = 1999;
var found = MovieTable().Rows.Find(Starwars);
if (found != null)
{
found["Cover"] = movieCover;
var movieListFound = movieList.Find(x => x.Name == Starwars[0]);
}
else
MessageBox.Show("Movie Not Found");
Save();
}

Categories

Resources