将 Json 到 Json 对象转换为 Json 数组(不是使用 JsonReader)

Convert a Json to Json object to Json array (NOT by using JsonReader)

这是我从 (.)json 文件中读取的 Json。

   {
      "steps": [
        {
          "stepType": "runFolderUpdate",
          "stepData": {
            "actionType": "update",
            "folderData": {
              "folderName": "New Folder 1",
              "dirName": "C:/demo/demo.xml",
              "machineAddress": "10.23.44.12"
            }
          }
        },
        {
          "stepType": "runFolderCreate",
          "stepData": {
            "actionType": "create",
            "actionData": {
              "folderName": "New Folder 2",
              "dirName": "C:/Demo",
              "machineAddress": "10.23.211.2"
            }
          }
        },
        { . . . },
        { . . . }        
      ]
    }

我的要求是从这个 Json 中得到一个数组,这样我就可以拥有所有字段并可以在“stepType”的帮助下访问它,并进一步在“actionType”值的帮助下。

对于 stepType = "runFolderUpdate"

       {
          "stepType": "runFolderUpdate",
          "stepData": {
            "actionType": "update",
            "folderData": {
              "folderName": "New Folder 1",
              "dirName": "C:/demo/demo.xml",
              "machineAddress": "10.23.44.12"
            }
          }
        }

对于 stepType = "runFolderCreate"

   {
      "stepType": "runFolderCreate",
      "stepData": {
        "actionType": "create",
        "actionData": {
          "folderName": "New Folder 2",
          "dirName": "C:/Demo",
          "machineAddress": "10.23.211.2"
        }
      }
    }

所以现在我有两个块,一个用于创建,一个用于更新,我可以继续访问每个要求的值,并且我不受 JSON 键的排列方式的限制。

我尝试使用 Newtonsoft 库中的 JsonReader 来做到这一点,但问题是它只能向前移动 reader,我无法返回。现在因为这是我们正在讨论的 JSON 文件,所以密钥的放置顺序应该无关紧要,但是对于 JsonReader 我束手无策。

举例来说,如果 stepType 低于 stepData 那么我不能使用 JsonReader 回到 stepData after 我知道我在说什么类型的 stepType。

我正在研究如何将此 steps 对象 Json 转换为数组,每个 blob 将充当我可以访问的信息块(就像我们在数组中做的那样,使用索引所以我不必担心键的顺序。

////////更新////////

我正在尝试做这样的事情....

JObject object = Read Json from file...
JArray array = object.get("steps");

现在我有了数组,基于 stepType 我可以继续...

这可能吗?

您可以使用自定义转换器相当轻松地将所有这些转换为 C# classes。 Newtonsoft 提供了一些非常有用的扩展点。因此,假设您具有以下 class 结构:

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

// Here we are telling the serialiser to use the converter
[JsonConverter(typeof(StepConverter))]
public class Step
{
    public string StepType { get; set; }
    public IStepData StepData { get; set; }
}

public interface IStepData
{
    string ActionType { get; set; }
}

public class RunFolderUpdate : IStepData
{
    public string ActionType { get; set; }

    //etc - you can fill in the rest here
}

public class RunFolderCreate : IStepData
{
    public string ActionType { get; set; }

    //etc - you can fill in the rest here
}

现在我们可以像这样实现转换器:

public class StepConverter : JsonConverter<Step>
{
    public override Step ReadJson(JsonReader reader, Type objectType, 
        [AllowNull] Step existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        var step = JObject.ReadFrom(reader);
        
        var stepType = step["stepType"].Value<string>();
        
        switch(stepType)
        {
            case "runFolderUpdate":
            
                
                return new Step
                {
                    StepType = stepType,
                    StepData = step["stepData"].ToObject<RunFolderUpdate>()
                };


            case "runFolderCreate":
                return new Step
                {
                    StepType = stepType,
                    StepData = step["stepData"].ToObject<RunFolderCreate>()
                };

        }
        throw new Exception("Errr, unknown step type!");
    }

    public override void WriteJson(JsonWriter writer, [AllowNull] Step value, 
        JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

最后你可以这样反序列化:

var result = JsonConvert.DeserializeObject<Root>(json);

您可以在工作中使用 JObject、JToken 和 JArray。

说你的 Json,你的 Json 以一个对象开始......它有一个“[”,后面是一个数组的表示,即 JArray......所以你可以做一些事情像这样...

因此,一旦您将“步数”作为这样的对象...

            JObject obj= null;

            using (StreamReader file = File.OpenText(filePath))
            using (JsonTextReader reader = new JsonTextReader(file))
            {
                obj = (JObject)JToken.ReadFrom(reader);
            }

            JToken token = obj.GetValue("steps");
            JArray array = (JArray) token;

现在你有一个看起来像这样的数组...因为它已经读取了“steps”

[
   { .... },
   { .... }
]

每个花括号都是你的数组索引(这里是 Json 对象)你可以使用 for 循环访问...

for (int i = 0; i < array.length(); i++) {

    //Now here get the next token which is an object again so you can
    //parse through it and perform your action as needed for create or update
}

这与 java 相同。

不用担心键的顺序,JObject 给了你自由,你不需要为此使用模型...模型确实是一种更简洁的方法,但它是紧密耦合的,所以如果你的 Json改了,没用。

如果您觉得正确,请标记为答案。