I have the json below
"Payload": {
"AdditionalProperties": [
{
"Key": "MyKey1",
"Value": "Value"
},
{
"Key": "MyKey2",
"Value": "Value"
}
]
}
By default this can be deserialized into an object with AdditionalProperties being deserialized into a List where AdditionalProperty just has 2 properties Key and Value - both strings
How can I get the json above to deserialize into a Dictionary<string, string> automatically?
At the moment I have had to create a separate property which isnt very nice
public List<AdditionalProperty> AdditionalProperties { get; set; }
public Dictionary<string, string> AdditionalPropertiesDictionary
{
get
{
return _additionalPropertiesDictionary ??= AdditionalProperties.ToDictionary(x => x.Key, x => x.Value);
}
set => _additionalPropertiesDictionary = value;
}
Paul
CodePudding user response:
I usually create a JsonConstructor in this case
Data data=JsonConvert.DeserializeObject<Data>(json);
public class Data
{
public Payload Payload { get; set; }
}
public class Payload
{
public Dictionary<string,string> AdditionalProperties { get; set; }
[JsonConstructor]
public Payload(JArray AdditionalProperties)
{
this.AdditionalProperties = AdditionalProperties
.ToDictionary(ap => (string) ap["Key"],ap=>(string)ap["Value"] );
}
}
CodePudding user response:
You can write a custom converter to deserialize they key-value pairs:
public class ArrayStringDictionaryConverter : JsonConverter<Dictionary<string, string>>
{
public override void WriteJson(JsonWriter writer, Dictionary<string, string> value, JsonSerializer serializer)
=> throw new NotImplementedException();
public override Dictionary<string, string> ReadJson(JsonReader reader, Type objectType, Dictionary<string, string> existingValue, bool hasExistingValue, JsonSerializer serializer)
{
var keyValuePairs = serializer.Deserialize<IEnumerable<KeyValuePair<string, string>>>(reader);
return new Dictionary<string, string>(keyValuePairs);
}
}
Then you'd use it as the following:
var json = @"{ ""Payload"": {
""AdditionalProperties"": [
{
""Key"": ""MyKey1"",
""Value"": ""Value""
},
{
""Key"": ""MyKey2"",
""Value"": ""Value""
}
]
}
}";
var root = JsonConvert.DeserializeObject<Root>(json, new ArrayStringDictionaryConverter());
foreach(var (k, v) in root.Payload.AdditionalProperties)
{
Console.WriteLine($"k: {k}, v: {v}");
}
// k: MyKey1, v: Value
// k: MyKey2, v: Value
public class Root
{
public Payload Payload {get;set;}
}
public class Payload
{
public Dictionary<string, string> AdditionalProperties {get;set;}
}
CodePudding user response:
You can write converter as below if you want
public class Payload
{
[JsonConverter(typeof(AdditionalPropertiesConverter))]
public Dictionary<string, string> AdditionalProperties { get; set; }
}
public class AdditionalPropertiesConverter : JsonConverter<Dictionary<string, string>>
{
public override void WriteJson(Newtonsoft.Json.JsonWriter writer, Dictionary<string, string>? value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override Dictionary<string, string>? ReadJson(Newtonsoft.Json.JsonReader reader, Type objectType, Dictionary<string, string>? existingValue, bool hasExistingValue,
JsonSerializer serializer)
{
var keyValuePairs = serializer.Deserialize<IEnumerable<KeyValuePair<string, string>>>(reader);
return new Dictionary<string, string>(keyValuePairs);
}
}
CodePudding user response:
To deserialise automatically with a dictionary you should have json structure like below.
{
"AdditionalProperties":
{
"MyKey1": ""Value",
"MyKey2":"Value"
}
}