How to find all types used by an object and its elements recursively?

I am trying to use a DataContractJsonSerializer to serialize and deserialize a C # object that contains an object [] of different types.

I need to find all types used by XmlRequest and the objects [] in it, so I pass the list of types to the DataContractJsonSerializer.

The [] object in XmlRequest will contain different types. TypeX, TypeY, string, int, TypeZ

var sr = new DataContractJsonSerializer(typeof(XmlRequest), knownTypes);

Xml request class:

[DataContract]
    public class XmlRequest
    {
        [DataMember]
        public object[] Parameters { get; set; }

        [DataMember]
        public string Name { get; set; }

    }
+3
source share
3 answers

I figured out how to do this using the configuration, instead of trying to detect these elements at runtime.

<system.runtime.serialization>
        <dataContractSerializer>
            <declaredTypes>
                <add type="Whatever.XmlRequest, Whatever, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
                    <knownType type="WhateverLibary.Parameter, WhateverLibary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
                </add>
            </declaredTypes>
        </dataContractSerializer>
    </system.runtime.serialization>
0
source

I see the answer to the question, as it is written, but I want to continue the study.

XmlRequest, , :

Object[] ary = new Object[] { new MyObject(), new MyObject() };

, :

Object[] ary = new Object[] { new MyObject(), new MyOtherObject() };

, Generics. , XmlRequest - , ..

, generics " ", Parameters .

+2
public void CollectTypes(Type type, HashSet<Type> types)
{
    if (types.Contains(type)) return;
    types.Add(type);

    foreach (FieldInfo fi in type.GetFields(BindingFlags.Instance | BindingFlags.Public))
    {
        if (!fi.IsInitOnly)
        {
            CollectTypes(fi.FieldType, types);
        }
    }

    foreach (PropertyInfo pi in type.GetProperties(BindingFlags.Instance | BindingFlags.Public))
    {
        if (pi.CanWrite && pi.CanRead)
        {
            CollectTypes(pi.PropertyType, types);
        }
    }
}

Using:

object[] parameters = ....;
HashSet<Type> types = new HashSet<Type>();
foreach(object p in parameters)
{
    if (p != null)
    {
      CollectTypes(p.GetType(), types)
    }
}

var sr = new DataContractJsonSerializer(typeof(XmlRequest), types.ToArray());

Verifying that this member is read-only is not required if the deserializer can write read-only members.

0
source

All Articles