Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serialize List<> of classes declared with internal modifier?

I'm trying to add XML serialization to a fairly trivial class structure in C#. Essentially, there's a single instance of a root class (call it AClass), which holds a List of several instances of some other class (call it AnotherClass):

[XmlRoot("RootNode")]
public class AClass {
    [XmlElement("ListNode")]
    internal List otherObjects { get; set; }
}

public class AnotherClass {
    [XmlAttribute("Name")]
    internal string name { get; set; }
}

When serializing, I'd like for both these classes to be serialized together - that is, if I serialize AClass, its list of AnotherClass gets serialized as well (see this question).

I have this mostly working, but the problem is that during serialization, XmlSerializer only seems to want to deal with public properties of the class - it doesn't serialize AnotherClass at all if the list is declared internal.

I tried making the assembly's internals visible to the serializer:

[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("System.Xml")]

That didn't seem to do anything. Is there a way I can get XmlSerializer to recursively serialize lists of objects that are declared internal?

like image 542
Tim Avatar asked Feb 14 '10 21:02

Tim


2 Answers

You're on the right track... except that the actual serialization is not performed by System.Xml, but by a dynamically generated assembly. You can't predict the name of that assembly (it's randomly generated), so you can't use it in the InternalsVisibleTo attribute.

The only solution is to pre-generate the XML serialization assembly. You can do that using the XML Serializer Generator Tool (Sgen.exe). The name of the generated assembly will be "YourAssembly.XmlSerializers" ; that's the name you have to use in the InternalsVisibleTo attribute.

like image 134
Thomas Levesque Avatar answered Oct 14 '22 20:10

Thomas Levesque


The idea of adding the InternalsVisibleTo attribute is a good one, but I think that the problem is that the Xml serialization code only looks for the public types in the assembly.
To my knowledge there is no way to make XmlSerializer serialize or deserialize internal types, and you will have to either declare the types as public or write your own serialization code.
Moreover, the XmlSerializer class documentation explicitly states that only public properties of the object will be serialized: "XML serialization is the process of converting an object's public properties and fields to a serial format (in this case, XML) for storage or transport", so it really looks like it's a design decision.

like image 45
Paolo Tedesco Avatar answered Oct 14 '22 19:10

Paolo Tedesco