System.Runtime.Serialization.DataContractSerializer ser = new System.Runtime.Serialization.DataContractSerializer(obj.GetType());
MemoryStream ms = new MemoryStream();
XmlWriter xdw = XmlWriter.Create(ms);
ser.WriteObject(xdw, obj);
Length of ms is 0
Why?
That works:
class Program
{
static void Main(string[] args)
{
var obj = "bugaga!";
System.Runtime.Serialization.DataContractSerializer ser = new System.Runtime.Serialization.DataContractSerializer(obj.GetType());
MemoryStream ms = new MemoryStream();
using (XmlWriter xdw = XmlWriter.Create(ms))
{
ser.WriteObject(xdw, obj);
}
Console.WriteLine(ms.Length);
}
}
[update] or just do xdw.Flush(), as already noticed
Related
Microsoft recommend to use XmlWriter instead of XmlTextWriter
https://msdn.microsoft.com/en-us/library/system.xml.xmltextwriter(v=vs.110).aspx
public string Serialize(BackgroundJobInfo info)
{
var stringBuilder = new StringBuilder();
using (var stringWriter = new StringWriter(stringBuilder, CultureInfo.InvariantCulture))
{
var writer = new XmlTextWriter(stringWriter);
new DataContractSerializer(typeof(BackgroundJobInfo)).WriteObject(writer, info);
}
return stringBuilder.ToString();
}
How to correctly use XmlWriter in my method instead of XmlTextWriter?
I'd use the factory method Create on XmlWriter class like:
var stringBuilder = new StringBuilder();
using(var writer = XmlWriter.Create(stringBuilder))
{
new DataContractSerializer(typeof(BackgroundJobInfo)).WriteObject(writer, info)
}
Or you can do it without XmlWriter
public static string Serialize(BackgroundJobInfo info)
{
string result = String.Empty;
using (var ms = new MemoryStream())
{
var sw = new StreamWriter(ms);
DataContractSerializer dcs = new DataContractSerializer(typeof(BackgroundJobInfo));
dcs.WriteObject(ms, info);
sw.Flush();
ms.Position = 0;
var sr = new StreamReader(ms);
result = sr.ReadToEnd();
}
return result;
}
didn't find a solution to following problem.
I had a working code for saving/loading a TreeView in a file but I want to save it to Properties.Settings.Default.
Unfortunately I get the error "no map for object" in this line:
object obj = bf.Deserialize(ms);
Here is the complete code for (de)serialization:
Don't know how to solve this one. :(
public static void SaveTreeView(TreeView tree)
{
using (MemoryStream ms = new MemoryStream())
{
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, tree.Nodes.Cast<TreeNode>().ToList());
ms.Position = 0;
var sr = new StreamReader(ms);
Properties.Settings.Default.tree = sr.ReadToEnd();
Properties.Settings.Default.Save();
}
}
public static void LoadTreeView(TreeView tree)
{
using (MemoryStream ms = new MemoryStream())
{
var sw = new StreamWriter(ms);
sw.WriteLine(Properties.Settings.Default.tree);
sw.Flush();
ms.Seek(0, SeekOrigin.Begin);
BinaryFormatter bf = new BinaryFormatter();
object obj = bf.Deserialize(ms);
TreeNode[] nodeList = (obj as IEnumerable<TreeNode>).ToArray();
tree.Nodes.AddRange(nodeList);
}
}
Anybody got an idea?
Thanks is advance.
Try this out
public static void SaveTree(TreeView tree)
{
using (var ms = new MemoryStream())
{
new BinaryFormatter().Serialize(ms, tree.Nodes.Cast<TreeNode>().ToList());
Properties.Settings.Default.tree = Convert.ToBase64String(ms.ToArray());
Properties.Settings.Default.Save();
}
}
public static void LoadTree(TreeView tree)
{
byte[] bytes = Convert.FromBase64String(Properties.Settings.Default.tree);
using (var ms = new MemoryStream(bytes, 0, bytes.Length))
{
ms.Write(bytes, 0, bytes.Length);
ms.Position = 0;
var data = new BinaryFormatter().Deserialize(ms);
tree.Nodes.AddRange(((List<TreeNode>)data).ToArray());
}
}
I seem to be getting some junk at the head of my serialized XML string. I have a simple extension method
public static string ToXML(this object This)
{
DataContractSerializer ser = new DataContractSerializer(This.GetType());
var settings = new XmlWriterSettings { Indent = true };
using (MemoryStream ms = new MemoryStream())
using (var w = XmlWriter.Create(ms, settings))
{
ser.WriteObject(w, This);
w.Flush();
return UTF8Encoding.Default.GetString(ms.ToArray());
}
}
and when I apply it to my object I get the string
<?xml version="1.0" encoding="utf-8"?>
<RootModelType xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/WeinCad.Data">
<MoineauPump xmlns:d2p1="http://schemas.datacontract.org/2004/07/Weingartner.Numerics">
<d2p1:Rotor>
<d2p1:Equidistance>0.0025</d2p1:Equidistance>
<d2p1:Lobes>2</d2p1:Lobes>
<d2p1:MajorRadius>0.04</d2p1:MajorRadius>
<d2p1:MinorRadius>0.03</d2p1:MinorRadius>
</d2p1:Rotor>
</MoineauPump>
</RootModelType>
Note the junk at the beginning. When I try to deserialize this
I get an error. If I copy paste the XML into my source minus
the junk prefix I can deserialize it. What is the junk text
and how can I remove it or handle it?
Note my deserialization code is
public static RootModelType Load(Stream data)
{
DataContractSerializer ser = new DataContractSerializer(typeof(RootModelType));
return (RootModelType)ser.ReadObject(data);
}
public static RootModelType Load(string data)
{
using(var stream = new MemoryStream(Encoding.UTF8.GetBytes(data))){
return Load(stream);
}
}
This fix seems to work
public static string ToXML(this object obj)
{
var settings = new XmlWriterSettings { Indent = true };
using (MemoryStream memoryStream = new MemoryStream())
using (StreamReader reader = new StreamReader(memoryStream))
using(XmlWriter writer = XmlWriter.Create(memoryStream, settings))
{
DataContractSerializer serializer =
new DataContractSerializer(obj.GetType());
serializer.WriteObject(writer, obj);
writer.Flush();
memoryStream.Position = 0;
return reader.ReadToEnd();
}
}
I am writing common functions to serialize the given object and List<object> as follows
public string SerializeObject(Object pObject)// for given object
{
try
{
String XmlizedString = null;
MemoryStream memoryStream = new MemoryStream();
XmlSerializer xs = new XmlSerializer(typeof(pObject));
XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
xs.Serialize(xmlTextWriter, pObject);
memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray());
return XmlizedString;
}
catch (Exception e) { System.Console.WriteLine(e); return null; }
}
public string SerializeObject(List<Object> pObject)// for given List<object>
{
try
{
String XmlizedString = null;
MemoryStream memoryStream = new MemoryStream();
XmlSerializer xs = new XmlSerializer(typeof(pObject));
XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
xs.Serialize(xmlTextWriter, pObject);
memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray());
return XmlizedString;
}
catch (Exception e) { System.Console.WriteLine(e); return null; }
}
first one is working fine. If I pass any type, it is successfully returning xml string.
CORRECTION: Compilation error has occurred for second one (Error: cannot convert from List<MyType> to List<object>.
I rewrite the second one as follows which solves my problem. Now it is serializing the given List<generic types>.
private string SerializeObject<T>(T source)
{
MemoryStream memoryStream = new MemoryStream();
XmlSerializer xs = new XmlSerializer(typeof(T));
XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
xs.Serialize(xmlTextWriter, source);
memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
string XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray());
return XmlizedString;
}
https://weblogs.asp.net/rajbk/Contents/Item/Display/345
The relevant code from the article:
private static string SerializeObject<T>(T source)
{
var serializer = new XmlSerializer(typeof(T));
using (var sw = new System.IO.StringWriter())
using (var writer = XmlWriter.Create(sw))
{
serializer.Serialize(writer, source);
return sw.ToString();
}
}
I have tried your two functions without much trouble. The only thing I changed was this line:
XmlSerializer xs = new XmlSerializer(typeof(pObject));
to this:
XmlSerializer xs = new XmlSerializer(pObject.GetType());
typeof() requires an actual type whereas GetType() returns the type of the object.
I encountered a problem with SOAP serialization and it would be great to find an answer. Here's a very simplified example:
public void Test()
{
StringBuilder sb = new StringBuilder();
StringWriter writer = new StringWriter(sb);
SoapReflectionImporter importer = new SoapReflectionImporter();
XmlTypeMapping map = importer.ImportTypeMapping(typeof(A));
XmlSerializer serializer = new XmlSerializer(map);
serializer.Serialize(writer, new A());
}
[Serializable]
public class A
{
public A()
{
BB = new B();
}
public int a;
public B BB;
}
[Serializable]
public class B
{
public int A1 { get; set; }
public int A2 { get; set; }
}
If I run method Test() then I get the following exception: System.InvalidOperationException: Token StartElement in state Epilog would result in an invalid XML document.
Would appreciate any help.
Use XmlWriter instead of StringWriter and do a writer.WriteStartElement("root");
This will work:
Stream s = new MemoryStream();
XmlWriter writer = new XmlTextWriter(s, Encoding.UTF8);
SoapReflectionImporter importer = new SoapReflectionImporter();
XmlTypeMapping map = importer.ImportTypeMapping(typeof(A));
XmlSerializer serializer = new XmlSerializer(map);
writer.WriteStartElement("root");
serializer.Serialize(writer, new A());
StreamReader sr = new StreamReader(s);
string data = sr.ReadToEnd();
Just a note,
The upper example will not work if the position of the stream is not set to the start of the stream. Like so:
Stream s = new MemoryStream();
XmlWriter writer = new XmlTextWriter(s, Encoding.UTF8);
SoapReflectionImporter importer = new SoapReflectionImporter();
XmlTypeMapping map = importer.ImportTypeMapping(typeof(A));
XmlSerializer serializer = new XmlSerializer(map);
writer.WriteStartElement("root");
serializer.Serialize(writer, new A());
s.Position = 0;
StreamReader sr = new StreamReader(s);
string data = sr.ReadToEnd();