Аттрибуты и сериализация

Язык Visual Basic на платформе .NET.

Модераторы: Ramzes, Sebas

natcap
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 234
Зарегистрирован: 25.06.2003 (Ср) 13:15
Откуда: Москва

Аттрибуты и сериализация

Сообщение natcap » 17.02.2015 (Вт) 2:31

Доброго времени суток :)

Искала - искала и не нашла..
Суть проблемы:
Есть объект который я сериализую (ХМЛ).

В нем было свойство
Код: Выделить всё
Public Property BranchesLst() As ObservableCollection(Of Branch)
        Get
            Return _branchesList
        End Get
        Set(ByVal value As ObservableCollection(Of Branch))
            _branchesList = value
        End Set
End Property


В последующей версии сделала ошибку. Вместо того чтобы создать новое свойство или сохранить имя типа спискового элемента, я оставила имя свойства старое, а имя класса спискового элемента сменила. Получилось:

Код: Выделить всё
Public Property BranchesLst() As ObservableCollection(Of Branch2)
        Get
            Return _branchesList
        End Get
        Set(ByVal value As ObservableCollection(Of Branch2))
            _branchesList = value
        End Set
End Property


И заметили это не сразу. В результате у части пользователей ( что еще не перешли на новую версию) в файле данных имя тега Branch, а у тех кто обновил Branch2, но при этом пропали старые данные

А теперь вопрос:
Как при помощи аттрибутов донести до сереализатора, что надо видеть и старые элементы и новые?

Пробовала вот так, ругается..

Код: Выделить всё
    <System.Xml.Serialization.XmlArray(), _
     System.Xml.Serialization.XmlArrayItem(GetType(Branch2), ElementName:="Branch2"), _
     System.Xml.Serialization.XmlArrayItem(GetType(Branch2), ElementName:="Branch")> _
   <DisplayName("Филиалы")> _
    Public Property BranchesLst() As ObservableCollection(Of Branch2)
        Get
            Return _branchesList
        End Get
        Set(ByVal value As ObservableCollection(Of Branch2))
            _branchesList = value
        End Set
    End Property
Медленно переезжаю с 6.0 на 2008 .... задавая тонны глупых вопросов :)

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2751
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 17.02.2015 (Вт) 12:10

Вроде так нельзя. Но можно сделать наследника с другим именем и у родителя поставить KnownType. Костыль, конечно, но должно помочь.

natcap
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 234
Зарегистрирован: 25.06.2003 (Ср) 13:15
Откуда: Москва

Re: Аттрибуты и сериализация

Сообщение natcap » 17.02.2015 (Вт) 15:42

Дело в том, что Branch2 и так наследник от Branch
Попробовала для Branch2 прописать <DataContract(), KnownType(GetType(Branch)))> _ говорит не знаю никаких KnownType и DataContract ... а System.Runtime.Serialization не видит никакого DataContractSerializer к каоторому вроде как эта радость относится
Медленно переезжаю с 6.0 на 2008 .... задавая тонны глупых вопросов :)

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2751
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 17.02.2015 (Вт) 15:48

Надо KnownType прописывать предку, а не наследнику.
И что-то тут не то... Я ещё подумаю.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2751
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 18.02.2015 (Ср) 0:50

Во-первых, KnownType - это для WCF, а для обычной сериализации XmlInclude.
Во-вторых, дальше преобразуем файл с помощью xslt к нужному виду и вроде всё работает.
От временного файла стоит избавиться - мне он был нужен для отладки преобразования.

Код: Выделить всё
<?xml version="1.0" encoding="cp866"?>
<Smth xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <BranchesLst>
    <Branch>
      <X>8</X>
    </Branch>
    <Branch2>
      <X>9</X>
    </Branch2>
    <Branch>
      <X>2</X>
    </Branch>
  </BranchesLst>
</Smth>
Код: Выделить всё
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" exclude-result-prefixes="xsi">
  <xsl:template match="Branch2">
    <Branch xsi:type="Branch2">
      <xsl:copy-of select="*"/>
    </Branch>
  </xsl:template>
  <xsl:template match="node() | @*">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()" />
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>
Код: Выделить всё
Imports System.Collections.ObjectModel
Imports System.Xml.Serialization
Imports System.IO
Imports System.Text
Imports System.Xml
Imports System.Xml.Xsl

<XmlInclude(GetType(Branch2))>
Public Class Branch
  Public Property X As Integer
End Class

Public Class Branch2
Inherits Branch
End Class

Public Class Smth
  Public Property BranchesLst As ObservableCollection(Of Branch)
End Class

Module VbStreets48960
  Public Sub Main()
    With New XslCompiledTransform
      .Load("transform.xslt")
      .Transform("data.xml", "results.xml")
    End With

    Using Reader As New XmlTextReader("results.xml")
      Dim Res As Smth = (New XmlSerializer(GetType(Smth))).Deserialize(Reader)
      Call (New XmlSerializer(GetType(Smth))).Serialize(Console.Out, Res)
    End Using

    Console.ReadKey()
  End Sub
End Module


Вернуться в Visual Basic .NET

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4

    TopList