Вопрос знатокам XMLSerializer'а.
От: .mif.  
Дата: 26.09.04 06:43
Оценка:
Используется стандартный XMLSerializer.

Проблема несколько запутанная, поэтому опишу полностью:

Есть некий объект RequestForm, который имеет проперти возвращающую типизированную коллекцию абстрактного типа. Хитрость в том, что эта проперти хранит не саму коллекцию, а ее сериализованную в XML строку, да еще и в виде массива байт. (Только не спрашивайте зачем это нужно) =). Тоесть, при установки проперти происходит сериализация, при считывании — десериализвация (с преобразованием массива байт в Stream и обратно).

Теперь. Необходимо сериализовать в XML весь исходных класс (вместе с пропертей этой). Сериализация проходит нормально, а десериализвая из этого же потока — нет. Не десериализуется коллекция. Причем и она, и ее элементы есть в XML, на вид — все окей.

При попытки десериализовать — десериализуется пустая коллекция. Дебаг сказал следущее: по непонятным мне причинам, после выхова Deserialize, во-первых, зачем-то вызывается get для этой самой проперти (для других пропертей — нет), во вторых, когда наконец происходит вызов set для этой проперти параметр value для него не содержит собственно десериализованной коллекции. Он предается как AdditionalFieldCollection но с количеством элементов — 0.

public class RequestForm
{
private byte[] _additionalFields = new byte[0];

...

public int RequestForm_ID
{
get
{
return _requestForm_ID;
}
set
{
requestForm_ID = value;
}
}
...

public AdditionalFieldCollection AdditionalFields
{
get
{
if ((_additionalFields == null) || (_additionalFields.Length == 0)) return null;
XmlSerializer ser = new XmlSerializer(typeof(AdditionalFieldCollection));
MemoryStream mst = GetAdditionalFieldsStream();
mst.Position = 0;
return (AdditionalFieldCollection)ser.Deserialize(mst);
}
set
{
SetAdditionalFields(value);
}
}
}

AdditionalFieldCollection — типизированная коллекция класса AdditionalField наследованная от CollectionBase. 100% сериализуется (проверял). (аттрибут:
[XmlInclude(typeof(BasicAdditionalField)), XmlInclude(typeof(AdditionalField))] указать не забыл

AdditionalField :

public abstract class AdditionalField
{
private string _name;
//protected Type _type;
private object _value;
...
и 2 get/set проверти над этими полями
}

Других полей нет.

BasicAdditionalField:

public class BasicAdditionalField: AdditionalField
{
public BasicAdditionalField()
{}
...
}

Есс-но, тоже сериализуется без проблем.

Если убрать строку:
if ((_additionalFields == null) || (_additionalFields.Length == 0)) return null;
то, есс-но, вылезает ошибка вызванная Null Reference , т.к десериализатор пытается обратиться к get, (а поле _additionalField, в котором хранится коллекция — пустое) чего быть, по идее, не должно.

Пробовал играться с атрибутом [XmlArray] — не помогло.

Проблема решается если сделать _additionalFields публичным, но это плохо. И с точки зрения дизайна, и с точки зрения читаемости XML, ибо сериализуется это поле в нечитаемую билеберду, есс-но.

Что я делаю не так? Где копать? Или это баг в десериализаторе?
Re: Вопрос знатокам XMLSerializer'а.
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 27.09.04 14:29
Оценка: +1
Здравствуйте, .mif., Вы писали:

M>При попытки десериализовать — десериализуется пустая коллекция. Дебаг сказал следущее: по непонятным мне причинам, после выхова Deserialize, во-первых, зачем-то вызывается get для этой самой проперти (для других пропертей — нет), во вторых, когда наконец происходит вызов set для этой проперти параметр value для него не содержит собственно десериализованной коллекции. Он предается как AdditionalFieldCollection но с количеством элементов — 0.


IList обрабатывается особым образом. Он не устанавливается, а десериализуются элементы и вызывается метод Add.

P.S. — для выделения кода пользуйся тегами форматирования, иначе он совсем нечитаем.
... << RSDN@Home 1.1.4 beta 3 rev. 190>>
AVK Blog
Re[2]: Вопрос знатокам XMLSerializer'а.
От: .mif.  
Дата: 27.09.04 17:15
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Здравствуйте, .mif., Вы писали:


M>>При попытки десериализовать — десериализуется пустая коллекция. Дебаг сказал следущее: по непонятным мне причинам, после выхова Deserialize, во-первых, зачем-то вызывается get для этой самой проперти (для других пропертей — нет), во вторых, когда наконец происходит вызов set для этой проперти параметр value для него не содержит собственно десериализованной коллекции. Он предается как AdditionalFieldCollection но с количеством элементов — 0.


AVK>IList обрабатывается особым образом. Он не устанавливается, а десериализуются элементы и вызывается метод Add.


Да, что то я забыл про это.
А ведь читал.

Я посмотрю тогда, как приду на работу следующий раз. Может быть там где-то происходит неприятность . Хотя, не должна.

Спасибо.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.