我有一组消息类,它包含代表特定类型消息所需数据的各种子类。当我将字符串反序列化为消息对象时,如果内部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
我看到了一些建议,但它们并不适合我:
Data Contract Serializer - 不幸的是我需要能够在序列化期间控制某些东西是属性还是元素,所以这不好。
在反序列化对象后使用使用反射的函数来检查是否标记了isNullable:= False
以及它是否为空。如果是这样,抛出异常。不幸的是,这只有在顶级必需属性为null时才有效。
到目前为止我的代码是:
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; XMLElement
和XMLAttribute
的属性。然后,当我反序列化它时,它会根据修饰的属性值抛出异常。