序列化 List<T> 问题

3
我面临着下一个序列化问题。我有一个MyObject类的列表,我想对其进行序列化,但无法以所需的方式执行。问题如下。我有这个类结构:
[XmlRoot(ElementName = "response")]
public class Response : List<MyObject> {}

[XmlElement("myObject")]
public class MyObject { ... }

经过序列化后,我得到了这个:
<response>
    <myObject>
        ...
    </myObject>
    <myObject>
        ...
    </myObject>
    <myObject>
        ...
    </myObject>
</response>

但我需要这一个:
<response>
    <myObejcts>
        <myObject>
            ...
        </myObject>
        <myObject>
            ...
        </myObject>
        <myObject>
            ...
        </myObject>
    </myObejcts>
</response>

我能否以任何方式获得所需的 XML 结构而无需添加属性?
public List<MyObject> {get; set;}

至于为什么我不能使用List属性,是因为我使用了Entity Framework,在这种情况下EF会在数据库中生成一些额外的不需要的表。

XmlElement可以在类级别上使用吗?有什么阻止你创建一个包装Response的额外类吗? - Icepickle
2个回答

1
您可以将完整的响应对象进行包装,然后使用该对象进行序列化吗?
[XmlRoot("response")]
public class ResponseWrapper<T>
{
    [XmlArray("MyObjects")]
    [XmlArrayItem]
    public List<T> Items { get; set; }

    public ResponseWrapper()
    {
    }

    public ResponseWrapper(List<T> items)
    {
        this.Items = items;
    }
}

这段文本的意思是:“然后生成如下输出:”。保留了HTML标签。
<?xml version="1.0"?>
<response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http:
//www.w3.org/2001/XMLSchema">
  <MyObjects>
    <MyObject>
      <ID>1</ID>
      <Name>Buck</Name>
    </MyObject>
    <MyObject>
      <ID>2</ID>
      <Name>Rogers</Name>
    </MyObject>
    <MyObject>
      <ID>3</ID>
      <Name>Flash</Name>
    </MyObject>
    <MyObject>
      <ID>4</ID>
      <Name>Gordon</Name>
    </MyObject>
  </MyObjects>
</response>

但是,它仍然需要您做一些额外的工作,是的 :)


-1

@Vsevywniy 再次您好,尽管我仍然认为创建一个包装器类是实现这一目标的最佳方法。另一个选项可以是实现 IXmlSerializable 接口来控制序列化并添加自定义元素。我能够将您的类结构序列化为期望的 XML,请查看以下代码:

public class Program
    {
        public static void Main(string[] args)
        {
            var products = new MyObjects()
            {
                new MyObject() {Id = 1, Name = "Dell"},
                new MyObject() {Id = 2, Name = "Sony"},
                new MyObject() {Id = 3, Name = "HP"}
            };

            var serializeObject = SerializeObject<MyObjects>(products);
            Console.WriteLine(serializeObject);
            Console.ReadLine();
        }

        public static string SerializeObject<T>(Object data)
        {
            string result;
            try
            {
                var xmlData = new MemoryStream();
                var xmlEncodedData = new XmlTextWriter(xmlData, Encoding.UTF8);
                var serial = new XmlSerializer(typeof(T));
                serial.Serialize(xmlEncodedData, data);
                xmlData.Position = 0;

                var reader = new StreamReader(xmlData);

                result = reader.ReadToEnd();

            }
            catch (Exception)
            {
                return string.Format("Error in return data");
            }

            return result;
        }
    }

    [XmlRoot("Response")]
    [Serializable]
    public class MyObjects : List<MyObject>, IXmlSerializable
    {

        public XmlSchema GetSchema()
        {
            return null;
        }

        public void ReadXml(XmlReader reader)
        {
            throw new NotImplementedException();
        }

        public void WriteXml(XmlWriter writer)
        {
            writer.WriteStartElement("MyObjects");
            foreach (var myObject in this)
            {
                new XmlSerializer(typeof(MyObject)).Serialize(writer, myObject);
            }
            writer.WriteEndElement();
        }
    }

    public class MyObject
    {
        public int Id { get; set; }
        public string Name { get; set; }


       }
}

数据库中有EF生成的额外响应表,但我不需要它。 - abilash
如果这是EF生成的类,你不能改变这个类的属性为XMLElement("MyObjects")。然后再创建另一个包装类,该类具有Response类型的属性。 - Gaurav Sharma
这不是EF生成的类,实际上是用于生成表的类(代码优先尝试)。我已经描述了我不使用这种情况,因为它会导致数据库存储困难(需要额外的存储空间)。 - abilash
@Vsevywniy 验证不允许我在评论中添加我的长代码,所以我已经编辑了我的答案。请查看代码。 - Gaurav Sharma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接