vb.net - 从 JSON 请求字符串中删除空数组/列表

标签 vb.net json.net

如何从 JSON 字符串中删除空数组和空列表?

我使用 vb.net 和 json.net 来实现此目的,但 json.net 无法从 JSON 字符串中删除空数组。我的 JSON 字符串是这样的:

{
    "jsonrpc": "2.0",
    "id": 1,
    "token": "tikenname",
    "method": "task.run",
    "params": {
        "commandList": [{
            "method": "Users.new",
            "params": {
                "userIds": "userid",
                "details": {
                    "credentials": {
                        "userName": "user",
                        "password": "pass"
                    },
                    "data": {
                        "rights": {},
                        "quota": {
                            "daily": {
                                "limit": {}
                            },
                            "weekly": {
                                "limit": {}
                            },
                            "monthly": {
                                "limit": {}
                            }
                        },
                        "wwwFilter": {}
                    },
                    "autoLogin": {
                        "addresses": {},
                        "addressGroup": {}
                    },
                    "vpnAddress": {},
                    "groups": {}
                }
            }
        },
        {
        "method": "set.save"
        }
        ]
    }
}

例如,我想从字符串中删除此部分

                    "data": {
                        "rights": {},
                        "quota": {
                            "daily": {
                                "limit": {}
                            },
                            "weekly": {
                                "limit": {}
                            },
                            "monthly": {
                                "limit": {}
                            }
                        },
                        "wwwFilter": {}
                    },
                    "autoLogin": {
                        "addresses": {},
                        "addressGroup": {}
                    },
                    "vpnAddress": {},
                    "groups": {}

这是我的类(class):

Public Class Account
    Public Property jsonrpc As String
    Public Property id As Integer
    Public Property token As String
    Public Property method As String
    Public Property params As New AccountSetParams
End Class

Public Class AccountSetParams
    Public Property commandList As New List(Of AccountSetCommandlist)
End Class

Public Class AccountSetCommandlist
    Public Property method As String
    Public Property params As New AccountSetUserDetails
End Class

Public Class AccountSetUserDetails
    Public Property userIds() As String
    Public Property details As New AccountSetDetails
    Public Property domainId As String
End Class

Public Class AccountSetDetails 
    Public Property credentials As New AccountSetCredentials 
    Public Property fullName As String 
    Public Property data As New AccountSetData 
    Public Property autoLogin As New AccountSetAutologin 
    Public Property vpnAddress As New AccountSetVpnaddress 
    Public Property groups() As New AccountSetGroup 
End Class
...

最佳答案

看起来 Json.Net 并没有提供一种简单的方法来排除您所描述的空列表或数组。从技术上讲,您要排除的大多数对象都不是空的:它们包含其他空的对象[包含其他对象...]。

因此,要实现此目的,您需要使用递归下降来过滤掉“无用”信息。我认为最好的方法可能是首先将对象图加载到 JObject (或 JArray)中,然后递归地将非空元素复制到新的 JObject (或 JArray),从最深的层次向上工作。然后,您可以序列化该副本以获得所需的精简 JSON。这种方法将允许您以通用方式处理任何对象结构。

这是一个可以解决问题的函数:

Function RemoveEmptyChildren(token As JToken) As JToken

    If token.Type = JTokenType.Object Then

        Dim copy As JObject = New JObject()

        For Each prop As JProperty In token.Children(Of JProperty)()

            Dim child As JToken = prop.Value
            If child.HasValues Then
                child = RemoveEmptyChildren(child)
            End If

            If Not IsEmpty(child) Then
                copy.Add(prop.Name, child)
            End If

        Next

        Return copy

    ElseIf token.Type = JTokenType.Array Then

        Dim copy As JArray = New JArray()

        For Each child As JToken In token.Children()

            If child.HasValues Then
                child = RemoveEmptyChildren(child)
            End If

            If Not IsEmpty(child) Then
                copy.Add(child)
            End If

        Next

        Return copy

    End If

    Return token

End Function

Function IsEmpty(token As JToken) As Boolean

    Return (token.Type = JTokenType.Array And Not token.HasValues) Or
           (token.Type = JTokenType.Object And Not token.HasValues) Or
           (token.Type = JTokenType.String And token.ToString() = String.Empty) Or
           (token.Type = JTokenType.Null)

End Function

这是一个演示如何使用该函数的简短示例:

Dim jsonString As String = _
    "{" + _
        """Int"" : 1," + _
        """String"" : ""Foo""," + _
        """EmptyString"" : """"," + _
        """EmptyArray"" : []," + _
        """EmptyObject"" : {}," + _
        """NullValue"" : null," + _
        """ArrayOfEmptyChildren"" : [ [], {}, """", null ]," + _
        """ChildObjectWithEmptyValues"" : {" + _
            """Array"" : []," + _
            """Object"" : {}," + _
            """Null"" : null," + _
            """String"" : """"" + _
        "}," + _
        """Boolean"" : true" + _
    "}"

Dim token As JToken = RemoveEmptyChildren(JToken.Parse(jsonString))

Console.WriteLine(token.ToString(Formatting.Indented))

这是上面示例的输出。请注意,仅保留非空信息。

{
  "Int": 1,
  "String": "Foo",
  "Boolean": true
}

注意:如果您从对象而不是 JSON 字符串开始,您仍然可以使用此函数。只需将上面示例中的 JToken.Parse(jsonString) 替换为 JToken.FromObject(yourObject)

此外,如果您想更改从输出中删除或不删除的内容,您可以修改 IsEmpty 函数以满足您的需求。

希望这有帮助。

关于vb.net - 从 JSON 请求字符串中删除空数组/列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18939274/

相关文章:

mysql - 通过参数化插入语句从 VB.net 发送到 Mysql 数据库的数据错误

c# - 截至目前,使用 COM 对象的正确方法是什么?

vb.net - 如何删除从类 VB.NET 的实例中添加的包装/自定义事件处理程序

c# - 使用 Json.NET 序列化泛型类中的 protected 属性

c# - 为什么会有 JConstructor?

c# - 解析来自 Httpwebrequest 的 Json 响应

vb.net - 非阻塞网络请求 vb.net

asp.net - AutoGenerateColumns ="true"时动态设置 gridview 列的宽度

c# - NewtonSoft JArray - 如何使用 LINQ 选择多个元素

c# - 如何根据另一个 JSON 属性有条件地反序列化 JSON 对象?