Общедоступные поля / свойства класса, производного от BindingList<T> не будут сериализованы

StackOverflow https://stackoverflow.com/questions/1225750

Вопрос

Я пытаюсь сериализовать класс, который является производным от Список привязок (Этаж), где Этаж это простой класс, который содержит только свойство Этаж.Высота

Вот упрощенная версия моего класса

[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();

И все же Тестовая строка приведенное выше заканчивается установкой следующего 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"?

Это было полезно?

Решение

Сериализация XML обрабатывает коллекции определенным образом и никогда не сериализует поля или свойства коллекции, только элементы.

Вы могли бы либо :

  • реализуйте IXmlSerializable, чтобы самостоятельно генерировать и анализировать XML (но это большая работа)
  • оберните свой BindingList в другой класс, в котором вы объявляете свои пользовательские поля (как предложено speps)

Другие советы

Короткий ответ здесь таков .NET обычно ожидает, что что-то быть коллекция ксор обладать свойствами.Это проявляется в нескольких местах:

  • сериализация 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 требует этого...

Это известная проблема с сериализацией 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 .Добавьте, и вы получите желаемый результат, я надеюсь, однако, я этого не пробовал.Имейте в виду, что игра с атрибутами является ключом к сериализации XML.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top