I'm using XMLSerializer to serialize a class into a XML. There are plenty of examples to this and save the XML into a file. However what I want is to put the XML into a string rather than save it to a file.
I'm experimenting with the code below, but it's not working:
public static void Main(string[] args)
{
XmlSerializer ser = new XmlSerializer(typeof(TestClass));
MemoryStream m = new MemoryStream();
ser.Serialize(m, new TestClass());
string xml = new StreamReader(m).ReadToEnd();
Console.WriteLine(xml);
Console.ReadLine();
}
public class TestClass
{
public int Legs = 4;
public int NoOfKills = 100;
}
Any ideas on how to fix this ?
Thanks.
You have to position your memory stream back to the beginning prior to reading like this:
XmlSerializer ser = new XmlSerializer(typeof(TestClass));
MemoryStream m = new MemoryStream();
ser.Serialize(m, new TestClass());
// reset to 0 so we start reading from the beginning of the stream
m.Position = 0;
string xml = new StreamReader(m).ReadToEnd();
On top of that, it's always important to close resources by either calling dispose or close. Your full code should be something like this:
XmlSerializer ser = new XmlSerializer(typeof(TestClass));
string xml;
using (MemoryStream m = new MemoryStream())
{
ser.Serialize(m, new TestClass());
// reset to 0
m.Position = 0;
xml = new StreamReader(m).ReadToEnd();
}
Console.WriteLine(xml);
Console.ReadLine();
There's the [Serializabe] attribute missing on class TestClass and you have to set the position of the memory stream to the beginning:
XmlSerializer ser = new XmlSerializer(typeof(TestClass));
MemoryStream m = new MemoryStream();
ser.Serialize(m, new TestClass());
m.Position = 0;
string xml = new StreamReader(m).ReadToEnd();
Console.WriteLine(xml);
Console.ReadLine();
Your memory stream is not closed, and is positioned at the end (next available location to write in). My guess is that you must Close it, or Seek to its beginning. The way you do you don't read anything because you are already at the end of stream. So add Seek() after you serialize objects. Like this:
XmlSerializer ser = new XmlSerializer(typeof(TestClass));
MemoryStream m = new MemoryStream();
ser.Serialize(m, new TestClass());
m.Seek(0, SeekOrigin.Begin); //<-- ADD THIS!
string xml = new StreamReader(m).ReadToEnd();
Console.WriteLine(xml);
Console.ReadLine();
Related
Memory stream can not be expanded exception thrown in Xml serialization with below code.
string message = string.Empty;
MyMessageTpe obj = new MyMessageTpe()
{
Age = 20
};
XmlSerializer xmlSerialization = new XmlSerializer(typeof(MyMessageTpe));
Stream str = new MemoryStream(ASCIIEncoding.UTF32.GetBytes(message));
TextWriter strWriter = new StreamWriter(str);
xmlSerialization.Serialize(strWriter, obj);
If you create a MemoryStream over a pre-allocated byte array, it can't expand. Just use without initializing its size.
string message = string.Empty;
MyMessageTpe obj = new MyMessageTpe() { Age = 20 };
XmlSerializer xmlSerialization = new XmlSerializer(typeof(MyMessageTpe));
Stream str = new MemoryStream();
TextWriter strWriter = new StreamWriter(str);
xmlSerialization.Serialize(strWriter, obj);
Memory stream is not expandable
MemoryStream()
Initializes a new instance of the MemoryStream class with an expandable capacity initialized to zero.
MemoryStream(Byte[])
Initializes a new non-resizable instance of the MemoryStream class based on the specified byte array.
I have Converted a the Different entities in a List and now I have a master list containing the many list of different models.
public static string xmlSerialize(List<Object> o)
{
XmlDocument xmlOut = new XmlDocument();
foreach(var i in o)
{
using (MemoryStream xmlStream = new MemoryStream())
{
//MemoryStream myMemStr = new MemoryStream();
XmlSerializer xmlSerializer = new XmlSerializer(i.GetType());
xmlSerializer.Serialize(xmlStream, i);
xmlStream.Position = 0;
xmlOut.Load(xmlStream);
}
}
return xmlOut.InnerXml;
}
The above method converts the multiple List into a XML. But this code Overwrites the previous XML string in every loop run.
Is There any solution to get the single XML for every entity.
IMHO - the simplest solution here is to load xml into temporary XmlDocument and then perform Import
Idea is the following
public static string xmlSerialize(List<Object> o)
{
XmlDocument xmlOut = new XmlDocument();
foreach(var i in o)
{
var tmpDoc = new XmlDocument();
using (MemoryStream xmlStream = new MemoryStream())
{
//MemoryStream myMemStr = new MemoryStream();
XmlSerializer xmlSerializer = new XmlSerializer(i.GetType());
xmlSerializer.Serialize(xmlStream, i);
xmlStream.Position = 0;
tmpDoc.Load(xmlStream);
}
var newNode = xmlOut.ImportNode(tmpDoc.DocumentElement.LastChild, true);
xmlOut.DocumentElement.AppendChild(newNode);
}
return xmlOut.InnerXml;
}
I am trying to serialize a class to be sent to a server where the server will use that object. I am using Microsoft's example of an asynchronous client/server setup for this: http://msdn.microsoft.com/en-us/library/bew39x2a.aspx I am using the binary formatter.
To test this, I am using this class:
[Serializable]
class Class1
{
public int x = 10;
public string banana = "banana";
}
and attempting to serialize it with:
Class1 example = new Class1();
IFormatter formatter = new BinaryFormatter();
Stream stream = new MemoryStream();
formatter.Serialize(stream, example);
in order to send it to the server, I need to send a string:
StreamReader reader = new StreamReader( stream );
string text = reader.ReadToEnd();
server.Send(text);
stream.Close();
but this doesn't work. I have tried converting the stream to a byte[] as seen here but I keep getting a Stream was unreadable exception when testing this in the debugger.
Try
Class1 example = new Class1();
IFormatter formatter = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream())
{
formatter.Serialize(ms, example);
ms.Position = 0;
StreamReader sr = new StreamReader(ms);
String text = sr.ReadToEnd();
server.Send(text);
}
I think that the part that got missed is resetting the position of MemoryStream to be able to read (think of it as rewinding for playback after recording)
I have a class that i store in a list.
I serialize it ...
XmlDocument xd = new XmlDocument();
MemoryStream ms = new MemoryStream();
XmlSerializer xm = new XmlSerializer(typeof(List<BugWrapper>));
xm.Serialize(ms, _bugs);
StreamReader sr = new StreamReader(ms);
string str = sr.ReadToEnd();
xd.Load(ms);
I looked into str and found it to be empty, the collection however has an object.
Any ideas into why this happens?
Yes - you're saving to the memory stream, leaving it at the end. You need to "rewind" it with:
ms.Position = 0;
just before you create the StreamReader:
xm.Serialize(ms, _bugs);
ms.Position = 0;
StreamReader sr = new StreamReader(ms);
string str = sr.ReadToEnd();
However, you then need to rewind it again before you load into the XmlDocument unless you remove those last two lines, which I suspect were just for debugging. Just for good measure, let's close the memory stream as well when we're done with it:
using (MemoryStream stream = new MemoryStream())
{
XmlSerializer serializer = new XmlSerializer(typeof(List<BugWrapper>));
seralizer.Serialize(stream, _bugs);
stream.Position = 0;
XmlDocument doc = new XmlDocument();
doc.Load(stream);
}
I have a simple 2D array of strings and I would like to stuff it into an SPFieldMultiLineText in MOSS. This maps to an ntext database field.
I know I can serialize to XML and store to the file system, but I would like to serialize without touching the filesystem.
public override void ItemAdding(SPItemEventProperties properties)
{
// build the array
List<List<string>> matrix = new List<List<string>>();
/*
* populating the array is snipped, works fine
*/
// now stick this matrix into the field in my list item
properties.AfterProperties["myNoteField"] = matrix; // throws an error
}
Looks like I should be able to do something like this:
XmlSerializer s = new XmlSerializer(typeof(List<List<string>>));
properties.AfterProperties["myNoteField"] = s.Serialize.ToString();
but that doesn't work. All the examples I've found demonstrate writing to a text file.
StringWriter outStream = new StringWriter();
XmlSerializer s = new XmlSerializer(typeof(List<List<string>>));
s.Serialize(outStream, myObj);
properties.AfterProperties["myNoteField"] = outStream.ToString();
Here's a Generic serializer (C#):
public string SerializeObject<T>(T objectToSerialize)
{
BinaryFormatter bf = new BinaryFormatter();
MemoryStream memStr = new MemoryStream();
try
{
bf.Serialize(memStr, objectToSerialize);
memStr.Position = 0;
return Convert.ToBase64String(memStr.ToArray());
}
finally
{
memStr.Close();
}
}
In your case you could call with:
SerializeObject<List<string>>(matrix);
Use the TextWriter and TextReader classes with the StringWriter.
To Wit:
XmlSerializer s = new XmlSerializer(typeof(whatever));
TextWriter w = new StringWriter();
s.Serialize(w, whatever);
yourstring = w.ToString();
IN VB.NET
Public Shared Function SerializeToByteArray(ByVal object2Serialize As Object) As Byte()
Using stream As New MemoryStream
Dim xmlSerializer As New XmlSerializer(object2Serialize.GetType())
xmlSerializer.Serialize(stream, object2Serialize)
Return stream.ToArray()
End Using
End Function
Public Shared Function SerializeToString(ByVal object2Serialize As Object) As String
Dim bytes As Bytes() = SerializeToByteArray(object2Serialize)
Return Text.UTF8Encoding.GetString(bytes)
End Function
IN C#
public byte[] SerializeToByteArray(object object2Serialize) {
using(MemoryStream stream = new MemoryStream()) {
XmlSerializer xmlSerializer = new XmlSerializer(object2Serialize.GetType());
xmlSerializer.Serialize(stream, object2Serialize);
return stream.ToArray();
}
}
public string SerializeToString(object object2Serialize) {
byte[] bytes = SerializeToByteArray(object2Serialize);
return Text.UTF8Encoding.GetString(bytes);
}