VB.Net创建一个要序列化的类

时间:2018-11-09 13:43:58

标签: xml vb.net serialization xmlserializer

我正在上第一堂课,然后对其进行序列化。我从未使用过序列化,并且遇到了一些问题。这是课程代码:

<XmlRoot([Namespace]:="FatturaElettronica")>
Public Class FatturaElettronica
    Public quantity As Integer

    Sub New()
        FatturaElettronicaHeader = New FatturaElettronicaHeader
    End Sub

    Property FatturaElettronicaHeader As FatturaElettronicaHeader
End Class

Public Class FatturaElettronicaHeader
    Sub New()
        DatiTrasmissione = New DatiTrasmissione
    End Sub

    Property DatiTrasmissione As DatiTrasmissione
End Class

Public Class DatiTrasmissione
    Sub New()
        Idtrasmittente = New idTrasmittente
        ContattiTrasmittente = New ContattiTrasmittente
    End Sub

    Property Idtrasmittente As idTrasmittente
    Property ProgressivoInvio As String
    Property FormatoTrasmissione As FormatoTrasmissioneType
    Property CodiceDestinatario As String
    Property ContattiTrasmittente As ContattiTrasmittente
    Property PecDestinatario As String
End Class

Public Class idTrasmittente
    Property IdPaese As String
    Property IdCodice As String
End Class

Public Class ContattiTrasmittente
    Property Telefono As String
    Property Email As String
End Class

Public Enum FormatoTrasmissioneType
    FPA12
    FPR12
End Enum

以下是我用于测试的一些代码:

Dim fattEle As New FatturaElettronica
Dim ns2 As New Xml.Serialization.XmlSerializerNamespaces()

ns2.Add("p", "FatturaElettronica")
Dim ser As Xml.Serialization.XmlSerializer = New Xml.Serialization.XmlSerializer(fattEle.GetType)
Dim stream As New IO.FileStream("c:/lavoro/example2.xml", IO.FileMode.Create)
ser.Serialize(stream, fattEle, ns2)
stream.Close()

这是我的输出XML:

<?xml version="1.0"?>
<p:FatturaElettronica xmlns:p="FatturaElettronica">
    <p:FatturaElettronicaHeader>
        <p:DatiTrasmissione>
            <p:Idtrasmittente />
            <p:FormatoTrasmissione>FPA12</p:FormatoTrasmissione>
            <p:ContattiTrasmittente />
        </p:DatiTrasmissione>
    </p:FatturaElettronicaHeader>
</p:FatturaElettronica>

首先,我想仅在根p:之前添加FatturaElettronica

第二,FormatoTrasmissione属性是Enum,但是在我的代码中没有设置任何内容。那么,为什么序列化假定值为FPA12而未分配该值?

最后但并非最不重要的一点...我想不序列化未填充的属性。 ContattiTrasmittente属性为空,但已序列化。为什么?

1 个答案:

答案 0 :(得分:1)

您在这里有三个独立的问题。让我们崩溃然后崩溃。

第一 ,我只想在根p:之前添加FatturaElettronica因为通过XmlRootAttribute.Namespace属性指定的名称空间将递归地应用于所有子元素,除非另有覆盖

由于您不希望这样做,因此最简单的预防方法是将<XmlType([Namespace]:="")>应用于FatturaElettronica。这会将空名称空间应用于FatturaElettronica的所有子元素,取代XmlRootAttribute.Namespace,该子元素现在仅应用于根元素本身。

第二 FormatoTrasmissione属性是Enum,但是在我的代码中没有设置任何属性。那么,为什么序列化假定值为FPA12而未分配该值?

默认情况下,XmlSerializer序列化所有非空公共属性和字段。由于enum是一种值类型,因此从定义上讲它不是null,因此枚举值属性总是被序列化的。

由于您不希望这样做,因此可以使用XML Schema Binding Support: MinOccurs Attribute Binding Support中记录的{propertyName}Specified条件序列化模式,并添加一个FormatoTrasmissioneSpecified布尔属性,该属性可跟踪{{1} }属性曾经明确设置过。如果不是,则序列化程序将不会序列化属性。

第三 ,我不希望序列化未填充的属性。 FormatoTrasmissione属性为空,但已序列化。为什么?发生这种情况的原因与ContattiTrasmittente属性被序列化的原因相同:FormatoTrasmissione将序列化所有非null的公共属性,并且您为XmlSerializer显式分配了一个值在ContattiTrasmittente构造函数中:

DatiTrasmissione

由于您不希望这样做,因此可以使用Properties in Windows Forms Controls: Defining Default Values with the ShouldSerialize and Reset Methods中记录的Public Class DatiTrasmissione Sub New() Idtrasmittente = New idTrasmittente ContattiTrasmittente = New ContattiTrasmittente End Sub 条件序列化模式,并添加一个布尔方法ShouldSerialize{PropertyName}(),当{{1 }}为空,或其所有属性为空。由于您要分配多个属性而未设置任何子值,因此可能需要添加多个此类方法。另外,您可以重新考虑设计,只在实际需要时才分配嵌套属性。

有关这两个条件序列化模式的更多详细信息,请参见 ShouldSerialize*() vs *Specified Conditional Serialization Pattern

将所有这些放在一起,您的代码应类似于:

ShouldSerializeContattiTrasmittente()

正在工作的vb.net提琴here