I have the following JSON :
{
"ruleName": "PhoneNumber",
"ruleSetInput": [
{
"PersonCode": "85782",
"PhoneTypeId": "1",
"PhoneClassId": "0",
"DiallingCode": "021",
"PhoneNumber": "9321662",
"Extension": "",
"Status": "",
"User": "2",
"DateCapturd": ""
}
]
}
The JSON won't always have the same fields in the ruleSetInput
node. I need to map each value under ruleSetInput
to a class with the following class:
public class Parameter
{
public string Name { get; set; }
public string Value { get; set; }
[JsonIgnore]
public int Type { get; set; }
}
As an example Parameter would be a list, and contain a value of :
Name: "PersonCode", Value: "85782"
How can I dynamically create this mapping? I have tried NewtonSoft.JSON but the mapping will only work if my object I am deseiralizing has this exact structure.
CodePudding user response:
You could make ruleSetInput
a Dictionary<string, string>
and then construct your Parameter
instances from the key-value pairs using ruleSetInput.Select(kv => new Parameter { Name = kv.Key, value = kv.Value }
CodePudding user response:
Solution 1: With JsonConverterAttribute
You can implement the JsonConverter
logic:
Iterate each
JObject
fromJArray
.Iterate each
JProperty
(key-value pair) fromJObject
.And add into the array of
List<Parameter>
type.
For RuleSetInput
property, apply the JsonConverterAttribute
.
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.Linq;
public class ParameterConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(Parameter));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
List<Parameter> parameters = new ();
JArray jArray = JArray.Load(reader);
foreach (JObject jObj in jArray)
{
foreach (JProperty jProp in (JToken)jObj)
{
parameters.Add(new Parameter
{
Name = jProp.Name,
Value = jProp.Value.ToString()
});
}
}
return parameters;
}
public override bool CanWrite
{
get { return false; }
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
public class Rule
{
public string RuleName { get; set; }
[JsonConverter(typeof(ParameterConverter))]
public List<Parameter> RuleSetInput { get; set; }
}
var rule = JsonConvert.DeserializeObject<Rule>(json);
Demo JsonConverterAttribute
@ .NET Fiddle
Solution 2: With JsonConstructorAttribute
The implementation logic is the same, you can move the logic into the constructor by applying JsonConstructorAttribute
.
public class Rule
{
[JsonConstructor]
public Rule(string ruleName, JArray ruleSetInput)
{
RuleName = ruleName;
List<Parameter> parameters = new ();
foreach (JObject jObj in ruleSetInput)
{
foreach (JProperty jProp in (JToken)jObj)
{
parameters.Add(new Parameter
{
Name = jProp.Name,
Value = jProp.Value.ToString()
});
}
}
RuleSetInput = parameters;
}
public string RuleName { get; set; }
public List<Parameter> RuleSetInput { get; set; }
}