我有一个 RESTful WCF 服务,我正在尝试向其发送任务列表。我在其他问题上发现你必须封装列表,我已经做到了,序列化看起来很顺利。
来自序列化列表的 XML 如下所示:
<?xml version="1.0" encoding="utf-8"?>
<MobileRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<TaskRequests xmlns="MyNameSpace">
<MobileTask>
<TaskArgs xsi:type="GetUser">
<Password>test</Password>
<UserName>t</UserName>
</TaskArgs>
<TaskID>1</TaskID>
<TaskType>GetUser</TaskType>
</MobileTask>
<MobileTask>
<TaskArgs xsi:type="GetUser">
<Password>test</Password>
<UserName>t2</UserName>
</TaskArgs>
<TaskID>2</TaskID>
<TaskType>GetUser</TaskType>
</MobileTask>
</TaskRequests>
</MobileRequest>
因此,MobileRequest
该类具有一个属性,即MobileTask
对象列表。该类的代码MobileRequest
非常简单,如下所示:
<Serializable(), DataContract(Name:="MobileRequest", [Namespace]:="MyNameSpace")> _
Public Class MobileRequest
<XmlArray()> <DataMember(Name:="TaskRequests")> _
Public TaskRequests As List(Of MobileTask) = New List(Of MobileTask)
Public Sub New()
Me.TaskRequests = New List(Of MobileTask)
End Sub
End Class
MobileTask 类如下所示:
<Serializable(), DataContract(Name:="MobileTask", [Namespace]:="MyNamespace"), _
KnownType(GetType(Obj.GetUser)), XmlInclude(GetType(Obj.GetUser))> _
Public Class MobileTask
Public Enum TypesOfTasks As Integer
Unknown = 0
GetUser = 1
End Enum
<DataMember(Name:="TaskID")> _
Public TaskID As Integer
<DataMember(Name:="TaskType")> _
Public TaskType As TypesOfTasks
<DataMember(Name:="TaskArgs")> _
Public TaskArgs As Object
End Class
TaskArgs 的类型取决于 TaskType。我为 TaskArgs 可能是的每种可能类型都包含了一个 XMLInclude 和 KnownType 标记。(这可能有点矫枉过正,但是当序列化的某些东西不起作用并且还没有尝试清理它时,我这样做了)
我在我的测试应用程序中使用的尝试反序列化 XML 的代码是:
Using logg As New System.IO.MemoryStream()
Using sw As New System.IO.StreamWriter(logg)
sw.Write(txtSource.Text)
sw.Flush()
If logg.Length > 0 Then
Using reader As New System.IO.StreamReader(logg)
logg.Position = 0
Dim ser As New System.Xml.Serialization.XmlSerializer(GetType(SMS_VendorObj.MobileRequest))
Dim results = ser.Deserialize(logg)
End Using
End If
End Using
End Using
这是来自一个简单的 winform 设置,它允许我粘贴 XML,所以txtSource
只是一个文本框,我将从序列化中获得的 XML 放入其中。
在运行测试应用程序时,我可以逐步执行上述反序列化代码,并且在该Dim results = ser.Deserialize(logg)
行results
是正确的类型之后,但MobileTask
列表不包含任何项目。
我是否遗漏了类文件中的某些内容,或者我尝试反序列化列表的方式有问题?
如果我错过了重要的代码,请告诉我,我会更新任何需要的东西。我还删掉了多余的部分,所以我可能在没有意识到的情况下剪掉了太多。
编辑:
班级GetUser
:
<Serializable(), DataContract([Namespace]:="MyNamespace")> _
Public Class GetUser
<DataMember(Name:="UserName")> _
Public UserName As String
<DataMember(Name:="Password")> _
Public Password As String
End Class
编辑#2:
在处理反序列化程序可能抛出的错误后,我发现反序列化过程在第 21 行第 3 位置抛出UnknownNode
异常,然后是UnknownElement
异常。详细信息表明预期元素是“:TaskRequests”。