Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将Json转换为Json对象到Json数组(不使用JsonReader)_C#_Json_.net_Json.net - Fatal编程技术网

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

C# 将Json转换为Json对象到Json数组(不使用JsonReader),c#,json,.net,json.net,C#,Json,.net,Json.net,这是我从(.)Json文件中读取的Json { "steps": [ { "stepType": "runFolderUpdate", "stepData": { "actionType": "update", "folderData":

这是我从(.)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=“runFolderCreate”

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

我试着使用Newtonsoft库中的JsonReader来实现这一点,但问题是它只是一个向前移动的阅读器,我无法返回。现在,由于这是我们正在讨论的JSON文件,所以键的放置顺序应该无关紧要,但是对于JsonReader,我的手被束缚住了

比如说,如果stepType低于stepData,那么我就不能使用JsonReader返回stepData,因为我知道我在说什么类型的stepType

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

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

我正试着做这样的事情

JObject object = Read Json from file...
JArray array = object.get("steps");
现在我有了数组,基于stepType我可以处理


这可能吗?

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

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
}
公共类根目录
{
公共列表步骤{get;set;}
}
//这里我们告诉序列化程序使用转换器
[JsonConverter(类型(步进转换器))]
公共类步骤
{
公共字符串StepType{get;set;}
公共IStepData StepData{get;set;}
}
公共接口IStepData
{
字符串ActionType{get;set;}
}
公共类RunFolderUpdate:IStepData
{
公共字符串ActionType{get;set;}
//等-你可以在这里填写其余的
}
公共类RunFolderCreate:IStepData
{
公共字符串ActionType{get;set;}
//等-你可以在这里填写其余的
}
现在我们可以像这样实现转换器:

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);
公共类StepConverter:JsonConverter
{
公共重写步骤ReadJson(JsonReader,类型objectType,
[AllowNull]步骤存在值,bool hasExistingValue,JsonSerializer序列化程序)
{
var step=JObject.ReadFrom(读卡器);
var stepType=step[“stepType”].Value();
开关(步进式)
{
案例“runFolderUpdate”:
返回新步骤
{
StepType=StepType,
StepData=步骤[“StepData”]。ToObject()
};
案例“runFolderCreate”:
返回新步骤
{
StepType=StepType,
StepData=步骤[“StepData”]。ToObject()
};
}
抛出新异常(“错误,未知步骤类型!”);
}
public override void WriteJson(JsonWriter writer,[AllowNull]步长值,
JsonSerializer(序列化程序)
{
抛出新的NotImplementedException();
}
}
最后,您可以像这样反序列化:

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);
var result=JsonConvert.DeserializeObject(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;
所以,一旦你得到像这样的“步骤”对象

            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;
现在您有了一个如下所示的数组…因为它已经读取了“步骤”

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

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
}
for(int i=0;i
这与java相同

不要担心键的顺序,JObject给了你自由,你不需要一个模型……模型确实是一种更干净的方式,但它是紧密耦合的,所以如果你的Json发生了变化,它就没有用了


如果您认为这是正确的,请标记为答案。

您看过该课程吗?您也可以使用。欢迎所有帮助,我将查看该课程,但对于Linq,我不确定我是否可以使用该课程(由于有许多限制)谢谢谢谢David,我看到了一些文档,这些文档正是您建议的……我相信这是一种对Json建模和反序列化的干净方法……我想如果我能得到JObject object=readJSonFromFile,然后得到JArray array=object.get(“步骤”);请告诉我是否可能……我之所以倾向于这样做,是因为有人建议我不要(由架构师)对我的json进行建模,因此我正在寻找我所说的方法。谢谢,这正是我所需要的。