Home > Blockchain >  How to Deserialize the following Json string in C#?
How to Deserialize the following Json string in C#?

Time:09-14

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.

Here is a enter image description here

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;
  • Related