Как сохранить таблицу данных, если она содержит объект, который отказывается сериализоваться? - PullRequest
2 голосов
/ 28 февраля 2010

Я храню объекты GData "Event" из API Google в виде данных (хорошо, я должен был привести их как объект, иначе они не вошли бы), и я могу получить полный доступ ко всем свойствам событий и использовать их для обновления Google, но я не могу сериализовать таблицу данных (или родительский набор данных) в файл, потому что:

Тип 'Google.GData.Calendar.EventEntry, Google.GData.Calendar, Version = 1.4.0.2, Culture = нейтральный, PublicKeyToken = aa6748391206b888' не реализует интерфейс IXmlSerializable, поэтому не может продолжить сериализацию.

Это происходит, пытаюсь ли я просто сериализовать как XML или двоичный файл, и я не могу найти способ обойти проблему; нельзя ли сохранить какую-либо структуру данных в файл тем или иным способом?

Чтобы установить контекст, я изначально сохранял GData EventFeed в формате XML, который потребовал около 30 секунд, чтобы выяснить, используя Google API myEventFeed.saveToXML, думая, что я просто перезагрузлю его позже ... Я потратил два дня, пытаясь верните xml обратно в объект EventFeed и теперь переключитесь на сохранение EventEntry из EventFeed вместо таблицы данных.

Так что мне удалось легко сохранить Feed в XML 1.0, но чтение его обратно в GData EventFeed было другой историей - Google предоставил вам myFeed.saveToXML, но без метода loadfromXML: - / В итоге я попытался добавить System. Runtime.Serialization для использования что-то вроде:

Dim reader As XmlReader = XmlReader.Create (fileName) Dim rssFeed As SyndicationFeed = SyndicationFeed.Load (читатель)

Поначалу это выглядело многообещающе, но не все данные в rssFeed, плюс мне все еще нужно вернуть данные в Google.GData.Calendar.EventFeed, прежде чем я смогу вызвать нужные мне методы, и я не могу понять, как это сделать. Я полагаю, можно просто скопировать наиболее важные биты данных из rssFeed в новые EventEntry или сделать то же самое с датируемыми данными, извлекая важные данные ... но это будет настолько не элегантно и рискованно.

Есть идеи, куда мне теперь повернуть? Я лаю не на тех деревьях?

Спасибо, Neil

VB .NET 3.5 VS 2008

Ответы [ 2 ]

2 голосов
/ 28 февраля 2010

Если у вас есть объект, который не хочет сериализовать, то нет способа заставить его сериализоваться.

Это означает, что вам нужно создать объект, который нужно сериализовать. Создайте XML-Serializable класс, который будет действовать как прокси для фактического класса. Ваш прокси будет иметь сериализуемое свойство, соответствующее каждому свойству исходного класса, который вы хотите видеть сериализованным:

public class Original
{
    private string _property1;
    private int _property2;

    public string Property1
    {
        get { return _property1; }
    }

    public int Property2
    {
        get { return _property2; }
    }
}

public class ProxyToOriginal
{
    private readonly Original _original;

    public ProxyToOriginal(Original original)
    {
        _original = original;
    }

    public string Property1
    {
        get { return _original.Property1; }
        set {  }
    }

    public int Property2
    {
        get { return _original.Property2; }
        set { }
    }
}
1 голос
/ 29 октября 2010

Для тех, кто сталкивается с этим вопросом, я думаю, что нашел ответ на проблему сериализации / десериализации XML GData. Я пытался сделать что-то похожее на OP, но EventFeed не сериализовался, поэтому я использовал метод SaveToXML, но, как указано в OP, метода LoadFromXML нет. Я наконец нашел метод Parse (), который работает:

        //first write the string to a file
        List<EventEntry> eventList = new List<EventEntry>();

        EventQuery query = new EventQuery(feed);
        AtomFeed eventFeed = _service.Query(query) as AtomFeed;
        XmlWriter writer = new XmlTextWriter("test.xml", new UTF8Encoding());

        eventFeed.SaveToXml(writer);
        writer.Close();

        //next, parse the string from the file
        Stream newFs = new FileStream("test.xml", FileMode.Open);

        AtomFeed newFeed = new AtomFeed(new Uri("http://someURI"), null);
        newFeed.Parse(newFs, AlternativeFormat.Atom);
        newFs.Close();
...