问题
I am trying to parse a JSON string into a C# class. however i can't get it to work.
the JSON looks like this
{
reports:
{
report:
{
id:"1"
step:
{
id:"2"
step:
[
{
id:"3"
step:
[
{
id:"4"
},
{
id:"5"
}
]
},
{
id:"6"
step:
{
id:"7"
}
}
]
}
}
}
}
i made a few classes to define the structure.
private class report
{
public mongoReports reports;
}
private class mongoReports
{
public mongoReport report;
}
private class mongoReport
{
public string id;
public step step;
}
private class step
{
public string id = "";
}
private class step
{
public string id = "";
public step step;
}
private class step
{
public string id = "";
public list<step> step;
}
the problem is in the 3 definitions that step can have. 1 without and step property, 1 with step being of type 'step' 1 with step being a list of objects of type 'step'.
how can I make a proper 'step' class that fits all these structures?
回答1:
I've prototyped something on dotnetfiddle if you'd like to have a look at that.
JSON Recursive Example
Basically you could have a 'root' step that implements lists of 'steps'. Each step then has a dependent list of steps. Both of these Lists are then parsed by the SingleOrArrayConverter and depending on whether there are 0,1 or n steps the List will get populated with the appropriate step objects. The custom converter is called recursively by the JSON deserialiser as it encounters a new Step object in the JSON source.
The Class structure would then look like:
public class Rootobject
{
public Reports reports { get; set; }
}
public class Reports
{
public Report report { get; set; }
}
public class Report
{
public string id { get; set; }
public RootStep step { get; set; }
}
public class RootStep
{
public string id { get; set; }
[JsonConverter(typeof(SingleOrArrayConverter<Step>))]
public List<Step> step { get; set; }
}
public class Step
{
public string id { get; set; }
[JsonConverter(typeof(SingleOrArrayConverter<Step>))]
public List<Step> step { get; set; }
}
The beauty of doing it this way is that you will be dealing directly with 'step' classes in your resultant object instead of dynamic objects or further JSON deserialisations.
The downside is that the deserialised JSON does not quite match the input JSON. I'm not sure if that's an issue for you, but if so then you could look at modifying the WriteJson method to accommodate that.
Hope that helps.
回答2:
If using a library like Newtonsoft JSON isn't an option, you might consider breaking the parse into a set of sub-parsers. Even constructors that take a string, expecting it to be JSON. So you would call
new reports(myJSON)
and report(string json) would in turn call new
mongoReports(reportJSON)
and eventually you would have a call that looks like:
new step(@"{
id:\"4\"
}"
If you don't want to embed that into the class itself, you could do the same thing using a factory pattern and have reports reportsCreator(string myJSON)
down to public stepCreator(string stepJSON)
But that would probably require changing the "exposure" (I can't remember the official term - public/private/protected) of your smaller classes.
来源:https://stackoverflow.com/questions/49923676/c-sharp-parse-recursive-json