在 .NET 中反序列化 json 时如何忽略丢失的节点
How to ignore missing nodes when deserialising json in .NET
某些 Shopify API 在未配置时不 return 节点,而不是 returning 空值。
JSON 示例
{
"orders": [
{
"id": 1,
"customer": {
"id": 001,
}
},
{
"id": 2
}
]
}
为了反序列化 Json,我需要在 class 对象中包含所有属性。
Public Class AllOrders
Public Property orders() As List(Of Order)
End Class
Public Class Order
Public Property id As Long?
Public Property customer() As Customer
End Class
Public Class Customer
Public Property id As Long?
End Class
如何在不使用复杂的 if
语句的情况下有效地跳过丢失的节点。
问题不在于 json 的反序列化,而是试图读取不存在的命名成员。
Dim AllOrders = JsonConvert.DeserializeObject(Of AllOrders)(GetOrders())
For Each order As Shopify.Order In AllOrders.orders
Dim test as order.customer.id
'Error NullReferenceException on customer
Next
这可以在 Json.Net 框架内处理吗?
JsonSerializerSettings
请注意,我已经尝试过以下设置。
Dim settings = New JsonSerializerSettings With {
.NullValueHandling = NullValueHandling.Ignore,
.MissingMemberHandling = MissingMemberHandling.Ignore
}
已更新以减少一些废话
Public Class AllOrders
Public Property orders() As List(Of TestOrder)
End Class
Public Class TestOrder
Public Property id As Long
Public Property customer As TestCustomer
Sub New()
_customer = New TestCustomer()
End Sub
End Class
Public Class TestCustomer
Public Property id As Long
End Class
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
Dim testString As String = <![CDATA[
{
"orders": [
{
"id": 1,
"customer": {
"id": 59,
}
},
{
"id": 2
}
]
}
]]>.Value
Dim settings = New JsonSerializerSettings With {.NullValueHandling = NullValueHandling.Include, .MissingMemberHandling = MissingMemberHandling.Ignore}
Dim all As AllOrders = JsonConvert.DeserializeObject(Of AllOrders)(testString, settings)
For Each order As TestOrder In all.orders
Dim test As Long = order.customer.id
' ouput is 59 and then 0 for the missing node (integer default value)
Next
End Sub
有几个客户端选项可以在一行中处理这个问题。
您可以使用空条件运算符 ?.
,如
Dim oneId = order.Customer?.Id
在这种情况下,结果是一个可为空的 Long
,但 Id
已经是一个可为空的 long,因此它不应更改后续处理,因为您已经需要考虑以下可能性它可能为空。如果缺失值只有一个“合理”值,则可以使用 GetValueOrDefault
获得保证值。
您可以使用 If
运算符的空合并形式,如
Dim guaranteedCustomer = If(order.Customer, defaultCustomer)
这需要谨慎,因为使用单个可变对象作为您的默认值可能会在以后当其中一个默认值发生变化从而更改所有默认项时出现严重错误。
某些 Shopify API 在未配置时不 return 节点,而不是 returning 空值。
JSON 示例
{
"orders": [
{
"id": 1,
"customer": {
"id": 001,
}
},
{
"id": 2
}
]
}
为了反序列化 Json,我需要在 class 对象中包含所有属性。
Public Class AllOrders
Public Property orders() As List(Of Order)
End Class
Public Class Order
Public Property id As Long?
Public Property customer() As Customer
End Class
Public Class Customer
Public Property id As Long?
End Class
如何在不使用复杂的 if
语句的情况下有效地跳过丢失的节点。
问题不在于 json 的反序列化,而是试图读取不存在的命名成员。
Dim AllOrders = JsonConvert.DeserializeObject(Of AllOrders)(GetOrders())
For Each order As Shopify.Order In AllOrders.orders
Dim test as order.customer.id
'Error NullReferenceException on customer
Next
这可以在 Json.Net 框架内处理吗?
JsonSerializerSettings
请注意,我已经尝试过以下设置。
Dim settings = New JsonSerializerSettings With {
.NullValueHandling = NullValueHandling.Ignore,
.MissingMemberHandling = MissingMemberHandling.Ignore
}
已更新以减少一些废话
Public Class AllOrders
Public Property orders() As List(Of TestOrder)
End Class
Public Class TestOrder
Public Property id As Long
Public Property customer As TestCustomer
Sub New()
_customer = New TestCustomer()
End Sub
End Class
Public Class TestCustomer
Public Property id As Long
End Class
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
Dim testString As String = <![CDATA[
{
"orders": [
{
"id": 1,
"customer": {
"id": 59,
}
},
{
"id": 2
}
]
}
]]>.Value
Dim settings = New JsonSerializerSettings With {.NullValueHandling = NullValueHandling.Include, .MissingMemberHandling = MissingMemberHandling.Ignore}
Dim all As AllOrders = JsonConvert.DeserializeObject(Of AllOrders)(testString, settings)
For Each order As TestOrder In all.orders
Dim test As Long = order.customer.id
' ouput is 59 and then 0 for the missing node (integer default value)
Next
End Sub
有几个客户端选项可以在一行中处理这个问题。
您可以使用空条件运算符 ?.
,如
Dim oneId = order.Customer?.Id
在这种情况下,结果是一个可为空的 Long
,但 Id
已经是一个可为空的 long,因此它不应更改后续处理,因为您已经需要考虑以下可能性它可能为空。如果缺失值只有一个“合理”值,则可以使用 GetValueOrDefault
获得保证值。
您可以使用 If
运算符的空合并形式,如
Dim guaranteedCustomer = If(order.Customer, defaultCustomer)
这需要谨慎,因为使用单个可变对象作为您的默认值可能会在以后当其中一个默认值发生变化从而更改所有默认项时出现严重错误。