在 C# 中使用 JsonConverter.Deserialize 打印 JSON 字段(值)时获取空(空白)值

Getting empty(blank) value while printing JSON field (value) using JsonConverter.Deserialize in C#

我正在尝试使用 NewtonSoft 解析 JSON(我的 JSON 是数组类型)。下面是它的样子...

{
  "steps": [
    {
      "stepsType": "runWizard",
      "wizardType": "demoServer",
      "config": {
        "mode": "add",
        "resourceName": "demo server 1",
        "activeDbPrimaryServer": {
          "serverName": "abc",
          "serverAddress": "abc.demo.local"
        },
        "activeDbCatalog": "demoActiveDB",
        "activeDBUserId": "sa",
        "activeDBPassword": "xyz",
      }
    }
  ]
}

我使用 JsonToC# 转换器创建了一个 class....

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ServerSetupWizardConsoleApp
{
    // Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse); 
    public class ActiveDbPrimaryServer
    {
        public string serverName { get; set; }
        public string serverAddress { get; set; }
    }

    public class Config
    {
        public string mode { get; set; }
        public string resourceName { get; set; }
        public ActiveDbPrimaryServer activeDbPrimaryServer { get; set; }
        public string activeDbCatalog { get; set; }
        public string activeDBUserId { get; set; }
        public string activeDBPassword { get; set; }
    }

    public class Step
    {
        public string stepsType { get; set; }
        public string wizardType { get; set; }
        public Config config { get; set; }
    }

    public class Root
    {
        public List<Step> steps { get; set; }
    }    
}

现在,当我尝试在另一个 class 中反序列化它时,我在控制台中得到的响应是空的... 我有一个 TEXT 从那里我正在阅读 JSON 然后将它存储在一个字符串类型变量中并使用该字符串对其进行反序列化。

public Object ReadJson()
        {
            string jsonText = File.ReadAllText("C:\Desktop\demo.json");

            var rootObject = (Root) JsonConvert.DeserializeObject(jsonText, typeof(Root));

            var activeDbAttr = (ActiveDbPrimaryServer)JsonConvert.DeserializeObject(jsonText, typeof(ActiveDbPrimaryServer));

            Console.WriteLine("Value : " + activeDbAttr.serverAddress);

        }

activeDbAttr.serverAddressCONSOLE

中没有给我任何信息

它打印 --> 值 :(“:”后没有任何内容,如空白)

谁能告诉我这里出了什么问题。我遵循了一些旧的答案,但没有达到可以修复它的地步。

你正在反序列化

var rootObject = (Root) JsonConvert.DeserializeObject(jsonText, typeof(Root));
var activeDbAttr = (ActiveDbPrimaryServer)JsonConvert.DeserializeObject(jsonText, typeof(ActiveDbPrimaryServer));

[第二个产生 null ... 空投到 ActiveDbPrimaryServer 产生 null.]

相同的字符串两次变成 2 种不同类型的对象,这些对象不共享公共基础 class(当然对象除外)。

您的文本代表 Root 或 ActiveDbPrimaryServer,而不是两者。 ActiveDbPrimaryServer 是配置 class 的成员,并且是 Step 的成员。 ....

单步执行您的图表 root.Step.Config .. 如果所有实例都已设置,您应该到达您的 ActibeDdPrimaryServer 实例

现场演示:https://dotnetfiddle.net/PuO8F8

这是一个简单的导航问题。

您反序列化为 Root 对象,而不是使用 属性 导航,您再次反序列化为另一个对象,跳到正确的位置。

var rootObject = JsonConvert.DeserializeObject<Root>(jsonText);
var activesDBs = json.steps.Select( x=> x.config.activeDbPrimaryServer).ToList();

结果:

Dumping object(System.Linq.SelectListIterator`2[Step,ActiveDbPrimaryServer])
[
   {
   serverAddress  : abc.demo.local
   serverName     : abc
   }
]

为什么失败了?

var jsonDB = JsonConvert.DeserializeObject<ActiveDbPrimaryServer>(GetJson());

告诉解析器 Json 是 ActiveDbPrimaryServer.
类型 解析器打开 Json 并找到第一个对象:

{
  "steps": [..]
}

寻找预期类型 ActiveDbPrimaryServer

的 属性
public class ActiveDbPrimaryServer
{
    public string serverName { get; set; }
    public string serverAddress { get; set; }
}

一无所获。它在那里结束并为您提供一个正确类型的对象,没有 属性 initialized

部分反序列化:

如果你只想反序列化你需要的部分,请参考 Newtonsoft 的文档:
Deserializing Partial JSON Fragments

JObject rootObj = JObject.Parse(GetJson());
// get JSON result objects into a list
IList<JToken> results = rootObj["steps"].Children() // Step is a list so we use `.Children()` 
                               ["config"]["activeDbPrimaryServer"].ToList();

IList<ActiveDbPrimaryServer> dbResults = new List<ActiveDbPrimaryServer>();
foreach (JToken result in results)
{
    // JToken.ToObject is a helper method that uses JsonSerializer internally
    ActiveDbPrimaryServer dbResult = result.ToObject<ActiveDbPrimaryServer>();
    dbResults.Add(dbResult);
}