自定义XMLSerializer

时间:2017-03-15 21:23:48

标签: xml vb.net xmlserializer

我有一组消息类,它包含代表特定类型消息所需数据的各种子类。当我将字符串反序列化为消息对象时,如果内部XML包含无效,则仍将使用null必需属性创建该对象。我希望它能抛出异常。

这里有一些样本:

<Serializable>
<XmlRoot("INTERFACE")>
Public Class WM_Interface_ISHP
    Inherits WM_Interface

    Private m_Shipments As List(Of WM_Shipment)

    <XmlElement(ElementName:="SHIPMENT", IsNullable:=False)>
    Public Property Shipments() As List(Of WM_Shipment)
        Get
            Return m_Shipments
        End Get
        Set(value As List(Of WM_Shipment))
            m_Shipments = value
        End Set
    End Property
End Class
<Serializable>
Public Class WM_Shipment
    Private m_Ship_ID As String
    Private m_Shipment_Type_CI As String
    Private m_Exp_Ship_DT_CI As String
    Private m_FDD_Flg_CI As String
    Private m_Ship_Lines As List(Of WM_Ship_Line)

    <XmlAttribute("SHIP_ID")>
    Public Property Ship_ID() As String
        Get
            Return m_Ship_ID
        End Get
        Set(value As String)
            m_Ship_ID = value
        End Set
    End Property

    <XmlAttribute("SHIPMENT_TYPE_CI")>
    Public Property Shipment_Type_CI() As String
        Get
            Return m_Shipment_Type_CI
        End Get
        Set(value As String)
            m_Shipment_Type_CI = value
        End Set
    End Property

    <XmlAttribute("EXP_SHIP_DT_CI")>
    Public Property Exp_Ship_DT_CI() As String
        Get
            Return m_Exp_Ship_DT_CI
        End Get
        Set(value As String)
            m_Exp_Ship_DT_CI = value
        End Set
    End Property

    <XmlAttribute("FDD_FLG_CI")>
    Public Property FDD_Flg_CI() As String
        Get
            Return m_FDD_Flg_CI
        End Get
        Set(value As String)
            m_FDD_Flg_CI = value
        End Set
    End Property

    <XmlElement(ElementName:="SHIP_LINE", IsNullable:=False)>
    Public Property Ship_Lines() As List(Of WM_Ship_Line)
        Get
            Return m_Ship_Lines
        End Get
        Set(value As List(Of WM_Ship_Line))
            m_Ship_Lines = value
        End Set
    End Property
End Class

我看到了一些建议,但它们并不适合我:

  1. Data Contract Serializer - 不幸的是我需要能够在序列化期间控制某些东西是属性还是元素,所以这不好。

  2. 在反序列化对象后使用使用反射的函数来检查是否标记了isNullable:= False以及它是否为空。如果是这样,抛出异常。不幸的是,这只有在顶级必需属性为null时才有效。

  3. 到目前为止我的代码是:

    Public Shared Function ValidatingDeserializer(Of T)(s As Stream) As T
        Dim deserialize As T = DirectCast(New XmlSerializer(GetType(T)).Deserialize(s), T)
    
        For Each pi As PropertyInfo In GetType(T).GetProperties()
            Dim xmlNull As Attribute = pi.GetCustomAttribute(GetType(XmlElementAttribute))
            If xmlNull IsNot Nothing Then
                Dim xmlNullInst As XmlElementAttribute = DirectCast(xmlNull, XmlElementAttribute)
                If xmlNullInst.IsNullable = False And IsNothing(pi.GetValue(deserialize)) = True Then
                    Throw New Exception(String.Format("XML Deserialization Error, Message = {0} can't be null.", pi.Name))
                End If
            End If
        Next
        Return deserialize
    End Function
    

    在我的示例中,如果未定义任何货件,则应该(并且)触发异常。但如果有shipment但没有ship_lines,则应触发异常,但不是。

    除非我绝对必须,否则我宁愿不使用XSD。我想创建一个基于XMlSerializer的自定义XMLSerializer,但会添加一个新的&#34;必需&#34; XMLElementXMLAttribute的属性。然后,当我反序列化它时,它会根据修饰的属性值抛出异常。

0 个答案:

没有答案