简体   繁体   English

(反)序列化 Json 与 System.Text.Json 和 Newtonsoft.Json

[英](De)serializing Json with System.Text.Json and Newtonsoft.Json

I'm working on a legacy system that works with IotHub SDK. The application uses both System.Text.Json (there's an agreement to use this for current & future development) and Newtonsoft.Json for (de)serializing JSON.我正在处理与 IotHub SDK 一起使用的遗留系统。该应用程序同时使用 System.Text.Json(已同意将其用于当前和未来的开发)和 Newtonsoft.Json(反)序列化 JSON。

I need to deserialize the following JSON into a Dictionary<string,object> because the value can either be a string or a JSON object:我需要将以下 JSON 反序列化为 Dictionary<string,object> 因为该值可以是字符串或 JSON object:

{
  "route1": "route 1 text",
  "route2": {
    "route": "route 2 text",
    "priority": 1,
    "timeToLiveSecs": 60
  }
}

What I expect is that the value would be deserialized as:我期望的是该值将被反序列化为:

  • route1 as string route1 作为字符串
  • route2 as object路线 2 为 object

But System.Text.Json deserializes both values as JsonElement.但是 System.Text.Json 将这两个值反序列化为 JsonElement。 And to get the value, a method like GetString() needs to be called (see last row)要获取值,需要调用像 GetString() 这样的方法(见最后一行) 在此处输入图像描述

Because of the usage combination of Newtonsoft & System.Text.Json in this legacy application, serializing this object with Newtonsoft doesn't work.由于 Newtonsoft 和 System.Text.Json 在此遗留应用程序中的使用组合,因此使用 Newtonsoft 序列化此 object 不起作用。

在此处输入图像描述

The deserialization & re-serialization only works when the same libraries were used in both process.反序列化和重新序列化仅在两个过程中使用相同的库时才有效。 And IoTHub SDK from Microsoft itself, uses Newtonsoft.Json.微软自己的 IoTHub SDK 使用 Newtonsoft.Json。

Is there a way to make both libraries work together in this case?在这种情况下,有没有办法让两个库协同工作? I find it dangerous to use either one to deserialize an object type with this behavior, when there's a chance 3rd party libraries may use another library.当第 3 方库有可能使用另一个库时,我发现使用其中任何一个来反序列化 object 类型都是危险的。

As taken from the official docs: "System.Text.Json is strict by default and avoids any guessing or interpretation on the caller's behalf, emphasizing deterministic behavior. The library is intentionally designed this way for performance and security. Newtonsoft.Json is flexible by default. This fundamental difference in design is behind many of the following specific differences in default behavior."从官方文档中获取:“System.Text.Json 默认情况下是严格的,避免代表调用者进行任何猜测或解释,强调确定性行为。库是为了性能和安全性而有意设计的。Newtonsoft.Json 是灵活的默认。这种设计上的根本差异是以下默认行为中许多特定差异的背后原因。” Source: https://learn.microsoft.com/en-us/do.net/standard/serialization/system-text-json/migrate-from-newtonsoft?pivots=do.net-7-0来源: https://learn.microsoft.com/en-us/do.net/standard/serialization/system-text-json/migrate-from-newtonsoft?pivots=do.net-7-0

The core principle between Newtonsoft and the Microsoft differs as you can see.如您所见,Newtonsoft 和 Microsoft 之间的核心原则不同。 Also stated in the docs: "JsonElement is what you can search and enumerate over, and you can use JsonElement to materialize JSON elements into .NET types."文档中还指出:“JsonElement 是您可以搜索和枚举的内容,您可以使用 JsonElement 将 JSON 元素具体化为 .NET 类型。”

As seen in your screenshot, System.Text.Json detects the right type (string) -> see the ValueKind property.如您的屏幕截图所示,System.Text.Json 检测到正确的类型(字符串)-> 请参阅 ValueKind 属性。 You can access the property and do your handling.您可以访问该属性并进行处理。 Other than that, no there is no way to use both libs interchangeably since they have a different approach.除此之外,没有办法可以互换使用这两个库,因为它们有不同的方法。

withJsonDeserializer["route1"].ValueKind

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM