Multiple root element (DataContractSerializer) - c#

I'm trying to deserialize file by using DataContractSerializer. I have such class:
[DataContract]
public class kontenerUstawienia
{
[DataMember]
public int[] stanGry;
[DataMember]
public int maxSize;
[DataMember]
public int[] stanOpcji;
[DataMember]
public int numerFlagi1;
[DataMember]
public int numerFlagi2;
public kontenerUstawienia()
{
}
(...)
}
Inside, after saving serialized class instance to the file, I read the file and try to deserialize:
try
{
zapiszObiektUstawien((kontenerUstawienia)deserializer.ReadObject(strumien));
}
catch (SerializationException e)
{
System.Diagnostics.Debug.WriteLine("\n\n\n\n++++++\n" +
e.Message
+ "\n+++++++++++++++++++++++++++++++++++++++++++++++");
}
catch prints me:
++++++
There was an error deserializing the object of type
WindowsPhoneGame1.kontenerUstawienia. There are multiple root elements. Line 1,
position 599.
+++++++++++++++++++++++++++++++++++++++++++++++
What am I doing wrong?
EDIT:
Here is code that I serialize and save:
public void zapiszDoPliku(string sciezkaDoPliku, IsolatedStorageFile katalog)
{
IsolatedStorageFileStream strumien = katalog.CreateFile(sciezkaDoPliku); // tworzenie pliku
MemoryStream ms = new MemoryStream();
StreamReader r = new StreamReader(ms);
DataContractSerializer serializer = new DataContractSerializer(typeof(kontenerUstawienia));
serializer.WriteObject(ms, this);
ms.Position = 0;
string daneDoZapisania = r.ReadToEnd();
byte[] bytes = Encoding.Unicode.GetBytes(daneDoZapisania);
strumien.Write(bytes, 0, bytes.Length);
ms.Close();
strumien.Close();
}
EDIT2:
File saved:
File is here

Are you sure that the file was empty before writing?

Related

How to correctly (de)serialize nested objects in c#?

EDIT: sorry the code is working as intended. I just failed to test properly. Sorry for your inconvenience
I found some code here on SO to store and load objects (Code in the end). Storing the file is correctly working, but getting the file into object back again is not working when you have a list of objects:
Executing
Block b = loadFile<Block>("file");
Console.WriteLine(b.allCoins.Count); //is 0
results in an empty List. Checking the xml file they are all correctly stored, which means that the loading is somehow not working. How can you correctly load the object?
Here is the block class:
[Serializable]
public class Block {
public struct Coin {
public string owner;
public string name;
public Coin(string n, string o) {
owner = o;
name = n;
}
};
public int name;
public List<string> hashOfParticles;
public int numberOfTransactions;
public List<Coin> allCoins;
}
}
Here is how i load the file into objects:
public static T loadFile<T>(string fileName) {
if (string.IsNullOrEmpty(fileName)) { return default(T); }
T objectOut = default(T);
try {
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(fileName);
string xmlString = xmlDocument.OuterXml;
using (StringReader read = new StringReader(xmlString)) {
Type outType = typeof(T);
XmlSerializer serializer = new XmlSerializer(outType);
using (XmlReader reader = new XmlTextReader(read)) {
objectOut = (T)serializer.Deserialize(reader);
reader.Close();
}
read.Close();
}
} catch (Exception ex) {
//Log exception here
}
return objectOut;
}
Here is the code which stores the file:
public static void storeFile<T>(T serializableObject, string fileName) {
if (serializableObject == null) { return; }
try {
XmlDocument xmlDocument = new XmlDocument();
XmlSerializer serializer = new XmlSerializer(serializableObject.GetType());
using (MemoryStream stream = new MemoryStream()) {
serializer.Serialize(stream, serializableObject);
stream.Position = 0;
xmlDocument.Load(stream);
xmlDocument.Save(fileName);
stream.Close();
Form1.instance.addToLog("Storing \"" + fileName + "\" succesful");
}
} catch (Exception ex) {
Console.WriteLine(ex.ToString());
Form1.instance.addToLog("Storing \"" + fileName + "\" NOT succesful");
}
}

'System.NotSupportedException' in mscorlib.ni.dll Memory stream is not expandable

I am getting the error "Exception thrown: 'System.NotSupportedException' in mscorlib.ni.dll Memory stream is not expandable" when trying to serialize and save an instance of a custom class object.
Here are my saving/loading methods:
public void SerializeObject<T>(T serializableObject, string fileName)
{
if (serializableObject == null) { return; }
try
{
XmlDocument xmlDocument = new XmlDocument();
XmlSerializer serializer = new XmlSerializer(serializableObject.GetType());
using (MemoryStream stream = new MemoryStream())
{
// convert string to stream
byte[] byteArray = Encoding.UTF8.GetBytes(fileName);
MemoryStream fileNameStream = new MemoryStream(byteArray);
serializer.Serialize(stream, serializableObject);
stream.Position = 0;
xmlDocument.Load(stream);
xmlDocument.Save(fileNameStream);
stream.Dispose();
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
Debug.WriteLine(TAG + serializableObject.ToString() + " saved");
}
public T DeSerializeObject<T>(string fileName)
{
if (string.IsNullOrEmpty(fileName)) { return default(T); }
T objectOut = default(T);
try
{
string attributeXml = string.Empty;
// convert string to stream
byte[] byteArray = Encoding.UTF8.GetBytes(fileName);
MemoryStream stream = new MemoryStream(byteArray);
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(stream);
string xmlString = xmlDocument.OuterXml;
using (StringReader read = new StringReader(xmlString))
{
Type outType = typeof(T);
XmlSerializer serializer = new XmlSerializer(outType);
using (XmlReader reader = XmlReader.Create(read))
{
objectOut = (T)serializer.Deserialize(reader);
reader.Dispose();
}
read.Dispose();
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
if (objectOut != null) Debug.WriteLine(TAG + objectOut.ToString() + " loaded");
return objectOut;
}
And here is the object class that I'm trying to save:
public class EntryDataType
{
readonly string TAG = "EntryDataType: ";
private static int idCounter = -1;
public int id;
private EntryDataType parentEdt;
public EntryDataType parentEdtProperty
{
get { return parentEdt; }
set { parentEdt = value; }
}
// row control is not serializable, so ignore it when saving
[XmlIgnore]
public RowControl linkedRowControl;
public int indent = -1;
public int index = -1;
public int linearIndex = -1;
private bool completed = false;
public bool completedProperty {
get { return completed; }
set
{
// set hidden state and set all children's hidden state, i.e. they will do the same
completed = value;
foreach (var item in childList)
{
item.linkedRowControl.SetCompleted(value);
}
}
}
public ChildList<EntryDataType> childList;
public bool bulletButtonChecked;
public string textboxText;
public EntryDataType()
{
// assign unique id to each entry
id = idCounter;
idCounter++;
//Debug.WriteLine(TAG + "new entry " + id + " created");
childList = new ChildList<EntryDataType>();
childList.parentEdtOfChildListProperty = this;
}
}
I've already rewritten the class to eliminate it's constructor's parameters, and to ignore the unserializeable RowControl member. I am just learning .NET and c# so don't fully know what I'm doing yet; any help is greatly appreciated. Thanks :)
OK, I think I see what you are trying to do - serialize and deserialize an object to/from a file. Your way is a bit complicated, it could be simplified, for example like this:
public static void SerializeObject<T>(T serializableObject, string fileName)
{
if (serializableObject == null) { return; }
try
{
XmlSerializer serializer = new XmlSerializer(serializableObject.GetType());
using (Stream stream = File.Open(fileName, FileMode.Create))
{
serializer.Serialize(stream, serializableObject);
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
public static T DeSerializeObject<T>(string fileName)
{
if (string.IsNullOrEmpty(fileName)) { return default(T); }
try
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
using (Stream stream = File.Open(fileName, FileMode.Open))
{
return (T)serializer.Deserialize(stream);
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
return default(T);
}
There is no need to read/write to a MemoryStream first. You can serialize and deserialize straight from the file.
Also, when using using, there is no need to dispose the object (like your stream.Dispose(); line) - that's what the dispose is for (with the added bonus that if there's an exception, the object will be disposed as well).
I haven't tried this with your class but it should work fine. Give it a try and see if it works.
byte[] byteArray = Encoding.UTF8.GetBytes(fileName);
MemoryStream fileNameStream = new MemoryStream();
...
xmlDocument.Save(fileNameStream);

There was an error reflecting type 'System.Collections.Generic.List`

I need for project in my study save to file serialize object list. I first time using serialize. I read many examples and i can't resolve my error. I getting error 'There was an error reflecting type 'System.Collections.Generic.List`'
This is my class to serialize
namespace projekt2
{
[Serializable()]
public class wezel : ICloneable
{
public Label text {get;set;}
public Ellipse el {get;set;}
public int id {get;set;}
public wezel(Label text, Ellipse el, int id)
{
this.text = text;
this.el = el;
this.id = id;
}
public wezel()
{
}
public object Clone()
{
return this.MemberwiseClone();
}
}
}
List declaration
public List <wezel> w= new List<wezel>();
And function what i try serialize
public void SerializeToXML(MainWindow window, Canvas canvas, int dpi, string filename)
{
string mystrXAML = XamlWriter.Save(canvas);
FileStream filestream = File.Create(filename);
StreamWriter streamwriter = new StreamWriter(filestream);
streamwriter.Write(mystrXAML);
streamwriter.Close();
filestream.Close();
XmlSerializer serializer = new XmlSerializer(typeof(List<wezel>));
TextWriter textWriter = new StreamWriter(#"wezly.xml");
serializer.Serialize(textWriter, w);
textWriter.Close();
}
Some one can now how to fix this error and serialize this list of object wezel?

Creating MTOM and Deserializing it

I have been using some code to create MTOM by using code from MSDN.
It seems that there is an error and I cannot understand where the problem lies as one of the users on the forum pointed out that there is an error.
The file (JPEG) data get corrupted after a de-serialization. The complete code is listed below.
public class Post_7cb0ff86_5fe1_4266_afac_bcb91eaca5ec
{
[DataContract()]
public partial class TestAttachment
{
private byte[] fileField;
private string filenameField;
[DataMember()]
public byte[] File
{
get
{
return this.fileField;
}
set
{
this.fileField = value;
}
}
[DataMember()]
public string Filename
{
get
{
return this.filenameField;
}
set
{
this.filenameField = value;
}
}
}
public static void Test()
{
string Filename = "Image.jpg";
byte[] file = File.ReadAllBytes(Filename);
TestAttachment Attachment = new TestAttachment();
Attachment.Filename = Filename;
Attachment.File = file;
MemoryStream MTOMInMemory = new MemoryStream();
XmlDictionaryWriter TW = XmlDictionaryWriter.CreateMtomWriter(MTOMInMemory, Encoding.UTF8, Int32.MaxValue, "");
DataContractSerializer DCS = new DataContractSerializer(Attachment.GetType());
DCS.WriteObject(TW, Attachment);
TW.Flush();
Console.WriteLine(Encoding.UTF8.GetString(MTOMInMemory.ToArray()));
var v = DeserializeMTOMMessage(Encoding.UTF8.GetString(MTOMInMemory.ToArray()));
File.WriteAllBytes(v.Filename,v.File);
}
public static TestAttachment DeserializeMTOMMessage(string MTOMMessage)
{
try
{
MemoryStream MTOMMessageInMemory = new MemoryStream(UTF8Encoding.UTF8.GetBytes(MTOMMessage));
XmlDictionaryReader TR = XmlDictionaryReader.CreateMtomReader(MTOMMessageInMemory, Encoding.UTF8, XmlDictionaryReaderQuotas.Max);
DataContractSerializer DCS = new DataContractSerializer(typeof(TestAttachment));
return (TestAttachment)DCS.ReadObject(TR);
}
catch
{
return null;
}
}
}
I would be grateful if someone can help me in pointing out where the problem is. I am new to XOP/MTOM and find it hard to track down where the error might be. Either serialization or de-serialization.
Thank you
There's a bug in your code.
Change your method call
MTOMInMemory.Position = 0;
DeserializeMTOMMessage(Encoding.UTF8.GetString(MTOMInMemory.ToArray()));
to
DeserializeMTOMMessage(MTOMInMemory.ToArray())
and the implementation to
public static TestAttachment DeserializeMTOMMessage(byte[] MTOMMessage)
{
try
{
MemoryStream MTOMMessageInMemory = new MemoryStream(MTOMMessage);
XmlDictionaryReader TR = XmlDictionaryReader.CreateMtomReader(MTOMMessageInMemory, Encoding.UTF8, XmlDictionaryReaderQuotas.Max);
DataContractSerializer DCS = new DataContractSerializer(typeof(TestAttachment));
return (TestAttachment)DCS.ReadObject(TR);
}
catch
{
return null;
}
}
what you've done was some double conversion from utf8 to byte array and vice versa, which ended up creating not the original byte array you were using

XmlSerialize a class and send it from client to server

I have 2 clases:
public class products
{
public string category;
public string name;
public double price;
public string desc;
public string version;
public string logoURL;
public string imgURL;
public string prod;
public string Category
{
set { categorie = value; }
get { return category; }
}
and:
[Serializable()]
public class groupProducts
{
public products[] produse;
}
I want to XmlSerialize the groupProducts class and send the data from a server via TCP conection to a client!
I've tried something like:
groupProducts gp = new groupProducts();
XmlSerializer xmlSel = new XmlSerializer(typeof(groupProducts));
TextWriter txtStream = new StreamWriter("xmlStreamFile.xml");
xmlSel.Serialize(txtStream, gp);
txtStream.Close();
try
{
Stream inputStream = File.OpenRead("xmlStreamFile.xml");
// declaring the size of the byte array to the length of the xmlfile
msg = new byte[inputStream.Length];
//storing the xml file in the byte array
inputStream.Read(msg, 0, (int)inputStream.Length);
//reading the byte array
communicator[i].Send(msg);
}
but it when I Deserialize it on the client side - the XML file has some weird data in it!
Do you have any idea what could it be? What am I doing wrong?
1- To be safe I would use an encoding while opening StreamWriter
2- In inputStream.Read(msg, 0, (int)inputStream.Length); Read does't guarantee that you will get inputStream.Length bytes from stream. You have to check the returned value.
3- You don't need a temp file. Use MemoryStream
XmlSerializer xmlSel = new XmlSerializer(typeof(groupProducts));
MemoryStream m = new MemoryStream();
xmlSel.Serialize(m);
communicator[i].Send(m.ToArray());

Categories