タスクのリストを送信しようとしている 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
オブジェクトのリストである 1 つのプロパティがあります。クラスのコード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
これは、XML を貼り付けることができる単純な winform セットアップからのものであるため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:デシリアライザー
がスローする可能性のあるエラーを処理した後、デシリアライゼーション プロセスがUnknownNode
例外をスローし、その後にUnknownElement
21 行目の位置 3 で例外がスローされていることがわかりました。