Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
反序列化两种类型的JSON消息_Json_Vb.net_Json.net - Fatal编程技术网

反序列化两种类型的JSON消息

反序列化两种类型的JSON消息,json,vb.net,json.net,Json,Vb.net,Json.net,我尝试使用返回JSON消息的web服务。每个方法都返回相关的JSON消息(通常是数组)或JSON错误消息(不是数组) UserList和错误消息的示例: [ { "id":1, "login":"john1", "full_name":"John Smith" }, { "id":2, "login":"anne", "full_name":"Anne Steward" } ] 因为代码不知道需要

我尝试使用返回JSON消息的web服务。每个方法都返回相关的JSON消息(通常是数组)或JSON错误消息(不是数组)

UserList和错误消息的示例:

[
   {
      "id":1,
      "login":"john1",
      "full_name":"John Smith"
   },
   {
      "id":2,
      "login":"anne",
      "full_name":"Anne Steward"
   }
]

因为代码不知道需要哪条消息,所以我创建了两个类,其中UserList继承自BaseResponse(一个错误消息类)。我使用了继承,因为所有其他方法(如GetCarList等)都适合返回错误消息。因此,无需多次声明错误字段。这必须是明智的——我将始终在同一个对象中获取或获取用户列表字段或错误消息字段

Public Class BaseResponse

    Public success As Boolean
    Public message As String

End Class


Public Class UserListResponse
    Inherits BaseResponse

    Public id As Integer
    Public login As String
    Public full_name As String

End Class
问题是,UserListResponse JSON消息是一个数组,而ErrorMessage JSON不是一个数组。因此,当JSON为UserList时,反序列化将起作用,但当JSON为错误消息时,反序列化将不起作用:

JsonConvert.DeserializeObject(Of List(Of UserListResponse))(ReceivedJSONMessage)

有什么好办法可以聪明地解决这个问题吗?

如果您确定两个返回类都在正确地反序列化json,那么本质上您只需要“我是列表还是字符串?”来询问一个路径或另一个路径

编辑8-30 好吧,所以我错过了,直到它被执行后你才知道,我的错。您可以在子程序内部执行逻辑,而不是函数,然后该函数在检查传递的泛型对象时直接执行逻辑。与此类似

Private Sub DetermineReturn(obj As Object)
  If obj.GetType = GetType(String) Then
      Console.WriteLine(CType(obj, String))
    ElseIf obj.GetType = GetType(List(Of String)) Then
      CType(obj, List(Of String)).ForEach(Sub(x) Console.WriteLine(x))
    Else
      Console.WriteLine("UnKnOwN!1!")
    End If
End Sub


Sub Main()
  Dim testError = "Oh Shoot Error!"
  Dim GoodStuff = New List(Of String)({"I", "am", "a", "list"})

  Console.WriteLine("FirstExample")
  DetermineReturn(testError)
  Console.WriteLine()
  Console.WriteLine("SecondExample")
  DetermineReturn(GoodStuff)
  Console.WriteLine()
  Console.WriteLine("ThirdExample")
  DetermineReturn(1)

  Console.ReadLine()
End Sub

基本上,您只需要在方法'DetermineReturn'中直接转换JSON,而不是在Console.WriteLines中。我正在解释传入的“obj”,使用反射获取其类型,然后可以安全地转换为该类型。因此,您可以将JSON返回的参数放在类似determinerReturn((YourJSONResult))的方法中,然后在该方法中对对象执行所需的任何转换。

谢谢。我确实理解这种方法。然而,我不明白在尝试反序列化之前,我应该把JSON放在哪里检查“我是列表还是字符串”。你能给我提供另一个关于JsonConvert.DeserializeObject的例子吗?你可以用JsonConvert.DeserializeObject(你的API调用)替换“DetermineReturn”中的“ReturnString”方法。实际上,您是在将一个返回作为一个通用的“对象”进行强制转换。您只需要区分输入来确定操作过程。我应该将JSON消息放在哪里来确定它的类型。此消息是字符串,因此只有在反序列化时,我们才能知道JSON内容是否可以反序列化为给定类型。那么我应该这样做吗:Dim s=DetermineReturn(MyJSONString的)?同时,我已经解决了这个问题,尝试将JSON消息反序列化为UserListResponse(没有继承的类),一旦失败,我捕获异常,然后反序列化为BaseResponse。最后,我创建了一个新类,它将两者结合起来。我不喜欢使用异常的方式,但我真的不理解您的解决方案。让我为您的案例编写一个稍微不同的更新示例,它可以更好地适应您的需要。谢谢更新。我还是觉得我们不明白。您将传递给testError和GoodStuff字符串或数组(.net types),其中我只有一条JSON消息(反序列化之前总是字符串),必须首先反序列化该消息并将其映射到我的.net复杂类型(就像我最初的问题中的类一样)。这里的问题取决于它将是哪个JSON消息(预期是2个中的1个),我需要将它反序列化为不同的类(业务对象)。
Private Sub DetermineReturn(obj As Object)
  If obj.GetType = GetType(String) Then
      Console.WriteLine(CType(obj, String))
    ElseIf obj.GetType = GetType(List(Of String)) Then
      CType(obj, List(Of String)).ForEach(Sub(x) Console.WriteLine(x))
    Else
      Console.WriteLine("UnKnOwN!1!")
    End If
End Sub


Sub Main()
  Dim testError = "Oh Shoot Error!"
  Dim GoodStuff = New List(Of String)({"I", "am", "a", "list"})

  Console.WriteLine("FirstExample")
  DetermineReturn(testError)
  Console.WriteLine()
  Console.WriteLine("SecondExample")
  DetermineReturn(GoodStuff)
  Console.WriteLine()
  Console.WriteLine("ThirdExample")
  DetermineReturn(1)

  Console.ReadLine()
End Sub