I'm trying to deserialize the following JSON:
{
"runtimeOptions": {
"tfm": "net6.0",
"frameworks": [
{
"name": "Microsoft.NETCore.App",
"version": "6.0.0"
},
{
"name": "Microsoft.WindowsDesktop.App",
"version": "6.0.0"
}
],
"configProperties": {
"MaxTargets" : "1024"
}
}
}
My model class looks like:
public class OptionalInclude
{
[JsonProperty("configProperties")]
public string ConfigProperties { get; set; }
[JsonProperty("tfm")]
public string Tfm { get; set; }
[JsonProperty("frameworks")]
public IList<Dictionary<string, string>> Frameworks { get; set; }
}
I'm trying to deserialize in this way, but I need the MaxTargets
value from the JSON:
var optionalIncludesConfig = File.ReadAllText(configPath);
result = (JObject)JsonConvert.DeserializeObject(optionalIncludesConfig);
var optionIncludes = new List<OptionalInclude>();
optionIncludes = result.ToObject<List<OptionalInclude>>();
CodePudding user response:
Firstly, the ConfigProperties
property on OptionalInclude
is not a string
type in the JSON, it is an object, so you should hard-type it like this:
public class ConfigProperties
{
[JsonProperty("MaxTargets")]
public string MaxTargets { get; set; }
}
Secondly, I think the frameworks
in your JSON would make more sense to have a Framework
class like this:
public class Framework
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("version")]
public string Version { get; set; }
}
and use an List<Framework>
instead. Lastly, you either need a class like this:
public class SomeClassName
{
[JsonProperty("runtimeOptions")]
public OptionalInclude RuntimeOptions { get; set; }
}
and then deserialize into that, or you need to parse the JSON into a JObject
, navigate it into the first layer of the object (the "runtimeOptions" object) and then parse that value into OptionalInclude
(I'd just hard-type it, personally).
Your resulting OptionalInclude
class should end up like this:
public class OptionalInclude
{
[JsonProperty("configProperties")]
public ConfigProperties ConfigProperties { get; set; }
[JsonProperty("tfm")]
public string Tfm { get; set; }
[JsonProperty("frameworks")]
public List<Framework> Frameworks { get; set; }
}
Then you should be able to deserialize it like this:
var jsonString = File.ReadAllText(configPath);
var result = JsonConvert.DeserializeObject<SomeClassName>(jsonString);
Note specifically that you can DeserializeObject
and use a specific object type instead of casting to a JObject
.
CodePudding user response:
Approach 1
You can access attributes of a JObject with the [ ] operator, for example assuming json is a JObject containing the json you provided:
var maxTargets = json["runtimeOptions"]["configProperties"]["MaxTargets"].ToString();
I find this approach fast, but it's easy to mess up with null tokens and such. Also, this isn't a very polished soluton.
Approach 2
I personally like to have classes for nested jsons, so for example:
public class ConfigProperties {
[JsonProperty("MaxTargets")]
public string MaxTargets { get; set; }
}
and then add it to your outer class:
public class OptionalInclude {
// other stuff
public ConfigProperties Properties { get; set; }
}
then you will be able do deserialize it. However, I see you are using a List of OptionalInclude. Assuming that you are cycling through such list:
foreach (var item in optionalIncludes) {
var maxTargets = item.Properties.MaxTargets;
// your logic
}
CodePudding user response:
configProperties is not an enumerable (list)
You can make:
public class Configuration
{
[JsonProperty("runtimeOptions")]
public RuntimeOptions RuntimeOptions { get; set; }
}
public class RuntimeOptions
{
[JsonProperty("tfm")]
public string Tfm { get; set; }
[JsonProperty("frameworks")]
public List<Framework> Frameworks { get; set; }
[JsonProperty("configProperties")]
public ConfigProperties ConfigProperties { get; set; }
}
public class Framework
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("version")]
public string Version { get; set; }
}
public class ConfigProperties
{
[JsonProperty("MaxTargets")]
public string MaxTargets { get; set; }
}
Then you code:
var configuration = File.ReadAllText(configPath);
var result = JsonSerializer.Deserialize<Configuration>(configuration);
string optionInclude = result.RuntimeOptions.ConfigProperties.MaxTargets;