简体   繁体   中英

How to use XmlInclude to specify types dynamically?

I have these classes which I use:

namespace defaultNamespace
{
    ...
    public class DataModel
    {
    }
    public class Report01
        {get; set;}
    public class Report02
        {get; set;}
}

And I have a method that creates the XML below.

public XmlDocument ObjectToXml(object response, string OutputPath)
{
    Type type = response.GetType();
    System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(type);
    MemoryStream stream = new MemoryStream();
    StreamWriter writer = new StreamWriter(stream, Encoding.UTF8);
    serializer.Serialize(writer, response);
    XmlDocument xmldoc = new XmlDocument();
    stream.Position = 0;
    StreamReader sReader = new StreamReader(stream);
    xmldoc.Load(sReader);
    stream.Position = 0;
    string tmpPath = OutputPath;
    while (File.Exists(tmpPath))
    {
        File.Delete(tmpPath);
    }
    xmldoc.Save(tmpPath);
    return xmldoc;
}

And I have two lists that has a Report01 and Report02 object.

List<object> objs = new List<object>();
List<object> objs2 = new List<object>();

Report01 obj = new Report01();
obj.prop1 = "aa";
obj.prop2 = "bb";
objs.Add(obj);

Report02 obj2 = new Report02();
obj2.prop1 = "cc";
obj2.prop2 = "dd";
objs2.Add(obj2);

When I try to create the XML like this:

ObjectToXml(objs, "c:\\12\\objs.xml");
ObjectToXml(objs2, "c:\\12\\objs2.xml");

I see this exception:

The type "Report01(or Report02)" was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically.

How can I solve this problem?

It's because your response.GetType() actually returns List<object> type and then you tried to serialize non expected type. Object don't know anything about your types and serializer for Object can't serialize your unknown types.

You can use BaseClass for your reports and XmlInclude to solve this exception:

[XmlInclude(typeof(Report01)]
[XmlInclude(typeof(Report02)]
public class BaseClass { }
public class Report01 : BaseClass { ... }
public class Report02 : BaseClass { ... }

List<BaseClass> objs = new List<BaseClass>();
List<BaseClass> objs2 = new List<BaseClass>();
// fill collections here
ObjectToXml(objs, "c:\\12\\objs.xml");
ObjectToXml(objs2, "c:\\12\\objs2.xml");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM