2

我正在尝试序列化一个派生自BindingList(Floor)的类,其中Floor是一个仅包含属性Floor.Height的简单类

这是我的课程的简化版本

[Serializable]
[XmlRoot(ElementName = "CustomBindingList")]
public class CustomBindingList:BindingList<Floor>
{
    [XmlAttribute("publicField")]
    public string publicField;
    private string privateField;

    [XmlAttribute("PublicProperty")]
    public string PublicProperty
    {
        get { return privateField; }
        set { privateField = value; }
    }
}

我将使用以下代码序列化 CustomBindingList 的实例。

XmlSerializer ser = new XmlSerializer(typeof(CustomBindingList));
StringWriter sw = new StringWriter();

CustomBindingList cLIst = new CustomBindingList();

Floor fl;

fl = new Floor();
fl.Height = 10;
cLIst.Add(fl);

fl = new Floor();
fl.Height = 10;    
cLIst.Add(fl);

fl = new Floor();
fl.Height = 10;
cLIst.Add(fl);

ser.Serialize(sw, cLIst);

string testString = sw.ToString();

然而上面的testString最终被设置为以下 XML:

<CustomBindingList xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">
    <Floor Height="10" />
    <Floor Height="10" />
    <Floor Height="10" />
</CustomBindingList>"

如何让“publicField”或“publicProperty”也序列化?

4

3 回答 3

3

这里的简短回答是,.NET 通常期望某些东西一个集合xor具有属性。这体现在几个地方:

  • xml序列化;集合的属性未序列化
  • 数据绑定;您不能将数据绑定到集合上的属性,因为它会隐式地将您带到第一个项目

在 xml 序列化的情况下,如果您认为它可能只是在客户端是有意义SomeType[]的......额外的数据会去哪里?

常见的解决方案是封装一个集合 - 即而不是

public class MyType : List<MyItemType> // or BindingList<...>
{
    public string Name {get;set;}
}

public class MyType
{
    public string Name {get;set;}
    public List<MyItemType> Items {get;set;} // or BindingList<...>
}

通常我不会有set一个集合属性,但XmlSerializer要求它......

于 2009-08-05T13:12:26.817 回答
2

XML 序列化以特定方式处理集合,从不序列化集合的字段或属性,仅序列化项。

您可以:

  • 实现 IXmlSerializable 以自己生成和解析 XML(但工作量很大)
  • 将您的 BindingList 包装在另一个类中,在其中声明您的自定义字段(如 speps 所建议的那样)
于 2009-08-05T13:09:29.843 回答
1

这是 XML 序列化和从集合继承的已知问题。

您可以在此处阅读更多信息:http: //social.msdn.microsoft.com/Forums/en-US/asmxandxml/thread/0d94c4f8-767a-4d0f-8c95-f4797cd0ab8e

你可以尝试这样的事情:

[Serializable]
[XmlRoot]
public class CustomBindingList
{
    [XmlAttribute]
    public string publicField;
    private string privateField;

    [XmlAttribute]
    public string PublicProperty
    {
        get { return privateField; }
        set { privateField = value; }
    }

    [XmlElement]
    public BindingList<Floor> Floors = new BindingList<Floor>();
}

这意味着您可以使用 Floors.Add 添加楼层,您将获得所需的结果,但我希望,我没有尝试过。请记住,使用属性是 XML 序列化的关键。

于 2009-08-05T13:02:22.280 回答