Общедоступные поля / свойства класса, производного от BindingList<T> не будут сериализованы
-
22-07-2019 - |
Вопрос
Я пытаюсь сериализовать класс, который является производным от Список привязок (Этаж), где Этаж это простой класс, который содержит только свойство Этаж.Высота
Вот упрощенная версия моего класса
[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.