У вас есть три отдельных вопроса здесь. Давайте тогда сломаться.
Сначала , я хотел бы добавить p:
только перед FatturaElettronica
, корнем. Это происходит потому, что пространство имен указано через XmlRootAttribute.Namespace
* Атрибут 1011 * применяется ко всем дочерним элементам рекурсивно , если не переопределено иное .
Так как вы не хотите этого, самый простой способ предотвратить это - применить <XmlType([Namespace]:="")>
к FatturaElettronica
. Это применяет пустое пространство имен ко всем дочерним элементам FatturaElettronica
, заменяя XmlRootAttribute.Namespace
, которое теперь будет применяться только к самому корневому элементу.
Второе , свойство FormatoTrasmissione
имеет значение Enum
, но в моем коде ничего не установлено. Итак, почему сериализация принимает значение FPA12
без присвоения этого значения?
По умолчанию XmlSerializer
сериализует все ненулевые общедоступные свойства и поля. Поскольку enum
является типом значения, он по определению ненулевой, и поэтому перечисляемые свойства всегда сериализуются.
Так как вы не хотите этого, вы можете использовать условный шаблон сериализации {propertyName}Specified
, который задокументирован в Поддержка привязки схемы XML: поддержка связывания атрибутов MinOccurs и добавить логическое свойство FormatoTrasmissioneSpecified
, которое отслеживает было ли когда-либо явно установлено свойство FormatoTrasmissione
. В противном случае сериализатор не будет сериализовать свойство.
Третий , я бы не хотел сериализовать свойства, которые не заполнены. Свойство ContattiTrasmittente
пустое, но сериализованное. Почему? Это происходит по той же причине, по которой сериализуется свойство FormatoTrasmissione
: XmlSerializer
будет сериализовать все ненулевые публичные свойства, и вы явно присвоили значение для ContattiTrasmittente
в конструкторе DatiTrasmissione
:
Public Class DatiTrasmissione
Sub New()
Idtrasmittente = New idTrasmittente
ContattiTrasmittente = New ContattiTrasmittente
End Sub
Поскольку вы этого не хотите, вы можете использовать шаблон условной сериализации ShouldSerialize{PropertyName}()
, который задокументирован в Свойства в элементах управления Windows Forms: определение значений по умолчанию с использованием методов ShouldSerialize и Reset , и добавить Логический метод ShouldSerializeContattiTrasmittente()
, который возвращает false, если ContattiTrasmittente
равно нулю или все его свойства равны нулю. Поскольку у вас есть несколько свойств, которые вы выделяете без установки дочерних значений, вам может потребоваться добавить несколько таких методов. В качестве альтернативы вы можете переосмыслить свой дизайн и выделять вложенные свойства только тогда, когда это действительно необходимо.
Подробнее о двух шаблонах условной сериализации см. ShouldSerialize * () vs * Указанный шаблон условной сериализации .
Собрав все это вместе, ваш код должен выглядеть примерно так:
<XmlRoot([Namespace]:="FatturaElettronica")>
<XmlType([Namespace]:="")> ' Fixed added empty namespace for all elements.
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
' By allocating ContattiTrasmittente you cause its value to be serialized by default
ContattiTrasmittente = New ContattiTrasmittente
End Sub
Property Idtrasmittente As idTrasmittente
Property ProgressivoInvio As String
' Fixed added FormatoTrasmissioneSpecified and made FormatoTrasmissione an explicitly implemented property
Private m_FormatoTrasmissione as FormatoTrasmissioneType
<XmlIgnore>
Public Property FormatoTrasmissioneSpecified as Boolean
Property FormatoTrasmissione As FormatoTrasmissioneType
Get
Return m_FormatoTrasmissione
End Get
Set
' For convenience set FormatoTrasmissioneSpecified automatically when the property is set publicly.
FormatoTrasmissioneSpecified = true
m_FormatoTrasmissione = value
End Set
End Property
Property CodiceDestinatario As String
' Fixed added ShouldSerializeContattiTrasmittente()
Property ContattiTrasmittente As ContattiTrasmittente
Public Function ShouldSerializeContattiTrasmittente() as Boolean
Return ContattiTrasmittente.ShouldSerialize()
End Function
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
' Fixed added an extension method to test whether a ContattiTrasmittente should be serialized.
Public Module ContattiTrasmittenteExtensions
<System.Runtime.CompilerServices.Extension()> _
Public Function ShouldSerialize(ByVal ContattiTrasmittente as ContattiTrasmittente) as Boolean
Return ContattiTrasmittente IsNot Nothing And (ContattiTrasmittente.Telefono IsNot Nothing Or ContattiTrasmittente.Email IsNot Nothing)
End Function
End Module
Public Enum FormatoTrasmissioneType
FPA12
FPR12
End Enum
Рабочая скрипка vb.net здесь .