xml - How to serialize object with List inside in C# using XElement? -
i have object members of different types this:
public class myobject { public string str1 = string.empty; public myenums.enum1 e1 = myenums.enum1.unknown; public bool done = false; };
i have dictionary
of these objects:
dictionary<string, myobject> myobjectsdic = new dictionary<string, myobject>();
and serializer this:
public static void toxml(string file, string collectionname, dictionary<string, object> collection) { xelement root = new xelement(collectionname); root.add(collection.select(x => new xelement("item", new xattribute("object", x.key), x.value.gettype().getfields().select(f => new xelement(f.name, f.getvalue(x.value)))))); root.save(file); }
the serializer tooks abstract dictionary
argument , need convert myobjectsdic
manually. may mistaken here.
toxml("myfile.xml", "myobjects", myobjectsdic.todictionary(p => p.key, p => (object)p.value));
i used this advice make serializer. works good, need add myobject new member
list<myenums.enum2> codes = new list<myenums.enum2>();
and store values here
var = new myobject {...}; a.codes.add(myenums.enum2.code1); a.codes.add(myenums.enum2.code2); myobjectsdic.add("obj1", a);
but these list serialized file like
<codes>code1code2<codes/>
without space or delimiter. , don't know how make more readable without modifications in serializer , without adding new odd code. idea got keep prepared string in myobject instead of list<...>. isn't graceful, simple , works. don't read these data, write , save log file.
or need change cool serializer?
upd.
i used solution below, i'm receiving exception on windows xp. on other os's works good. modified code make helper
not class extension
.
exception during dumping myobjectsdic: there error reflecting type 'myobject'.
@ system.xml.serialization.xmlreflectionimporter.importtypemapping(typemodel model, string ns, importcontext context, string datatype, xmlattributes a, boolean repeats, boolean openmodel, recursionlimiter limiter) @ system.xml.serialization.xmlreflectionimporter.importelement(typemodel model, xmlrootattribute root, string defaultnamespace, recursionlimiter limiter) @ system.xml.serialization.xmlreflectionimporter.importtypemapping(type type, xmlrootattribute root, string defaultnamespace) @ system.xml.serialization.xmlserializer..ctor(type type, string defaultnamespace) @ system.xml.serialization.xmlserializer..ctor(type type) @ myxmlserializerhelper.serializetoxelement[t](t obj, xmlserializer serializer, boolean omitstandardnamespaces) in myxmlserializerhelper.cs:line 16 @ myxmlserializerhelper. <serializetofile>b__0[t](keyvaluepair'2 x) in myxmlserializerhelper.cs:line 5
the idea have - different versions of framework or other religious issues on xp... unfortunately, can't install other software or .net version in production.
rather attempting use reflection manually serialize myobject
class, can use xmlserializer
serialize dictionary values directly xelement
using following methods, include result in element tree building:
public static class xobjectextensions { public static xelement serializetoxelement<t>(this idictionary<string, t> collection, string collectionname) { return new xelement(collectionname, collection.select(x => new xelement("item", new xattribute("object", x.key), x.value.serializetoxelement().elements()))); } public static xelement serializetoxelement<t>(this t obj, xmlserializer serializer = null, bool omitstandardnamespaces = true) { var doc = new xdocument(); using (var writer = doc.createwriter()) { xmlserializernamespaces ns = null; if (omitstandardnamespaces) (ns = new xmlserializernamespaces()).add("", ""); // disable xmlns:xsi , xmlns:xsd lines. (serializer ?? new xmlserializer(obj.gettype())).serialize(writer, obj, ns); } var element = doc.root; if (element != null) element.remove(); return element; } }
this automatically causes fields , properties of myobject
serialized properly. using this, resulting xml like:
<myobjects> <item object="obj1"> <str1>test object</str1> <e1>unknown</e1> <done>false</done> <codes> <enum2>code1</enum2> <enum2>code2</enum2> </codes> </item> </myobjects>
Comments
Post a Comment