I want to convert/map a JSON result that can have a selection of different types in its properties;
For example:
"randomProperties": [
{
"name": "foo",
"value": 22
},
{
"name": "bar",
"value": "somestring"
},
{
"name": "foobar",
"value": {
"type": "sometype",
"currency": "EUR",
"amount": 20,
}
},
{
"name": "entity",
"value": {
"typeId": "key-value-document",
"id": "36cxx0f3-6b76-4d7b-8ea7-577fe44ab308"
}
}
]
I would like to convert this to this model:
public class RandomProperties
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("value")]
public ValueObject ValueObject { get; set; }
[JsonProperty("value")]
public int? ValueInt { get; set; }
[JsonProperty("value")]
public string ValueString { get; set; }
}
public class ValueObject
{
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("currency")]
public string Currency { get; set; }
[JsonProperty("amount")]
public int? Amount { get; set; }
[JsonProperty("typeId")]
public string TypeId { get; set; }
[JsonProperty("id")]
public string ValueId { get; set; }
}
I tried to use the JsonConverter, but i could only manage to keep one of the types. How would I map a random result like this?
CodePudding user response:
It would look something like this:
namespace QuickType
{
using System;
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public partial class RandomProperties
{
[JsonProperty("randomProperties")]
public RandomProperty[] RandomPropertiesRandomProperties { get; set; }
}
public partial class RandomProperty
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("value")]
public ValueUnion Value { get; set; }
}
public partial class ValueClass
{
[JsonProperty("type", NullValueHandling = NullValueHandling.Ignore)]
public string Type { get; set; }
[JsonProperty("currency", NullValueHandling = NullValueHandling.Ignore)]
public string Currency { get; set; }
[JsonProperty("amount", NullValueHandling = NullValueHandling.Ignore)]
public long? Amount { get; set; }
[JsonProperty("typeId", NullValueHandling = NullValueHandling.Ignore)]
public string TypeId { get; set; }
[JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)]
public string Id { get; set; }
}
public partial struct ValueUnion
{
public long? Integer;
public string String;
public ValueClass ValueClass;
public static implicit operator ValueUnion(long Integer) => new ValueUnion { Integer = Integer };
public static implicit operator ValueUnion(string String) => new ValueUnion { String = String };
public static implicit operator ValueUnion(ValueClass ValueClass) => new ValueUnion { ValueClass = ValueClass };
}
internal static class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
Converters =
{
ValueUnionConverter.Singleton,
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
},
};
}
internal class ValueUnionConverter : JsonConverter
{
public override bool CanConvert(Type t) => t == typeof(ValueUnion) || t == typeof(ValueUnion?);
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
{
switch (reader.TokenType)
{
case JsonToken.Integer:
var integerValue = serializer.Deserialize<long>(reader);
return new ValueUnion { Integer = integerValue };
case JsonToken.String:
case JsonToken.Date:
var stringValue = serializer.Deserialize<string>(reader);
return new ValueUnion { String = stringValue };
case JsonToken.StartObject:
var objectValue = serializer.Deserialize<ValueClass>(reader);
return new ValueUnion { ValueClass = objectValue };
}
throw new Exception("Cannot unmarshal type ValueUnion");
}
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
{
var value = (ValueUnion)untypedValue;
if (value.Integer != null)
{
serializer.Serialize(writer, value.Integer.Value);
return;
}
if (value.String != null)
{
serializer.Serialize(writer, value.String);
return;
}
if (value.ValueClass != null)
{
serializer.Serialize(writer, value.ValueClass);
return;
}
throw new Exception("Cannot marshal type ValueUnion");
}
CodePudding user response:
try this, and you will have to fix classes too
var randomPropertiesParsed = JObject.Parse(json);
var rp = new RandomProperties();
foreach (JObject item in (JArray)randomPropertiesParsed["randomProperties"])
{
switch (item["value"].Type.ToString())
{
case "String":
rp.ValueString = item.ToObject<ValueString>();
break;
case "Integer":
rp.ValueInt = item.ToObject<ValueInt>();
break;
case "Object":
if (item["value"]["type"] != null)
rp.ValueObjectType = item.ToObject<ValueObject>();
else
rp.ValueObjectTypeId = item.ToObject<ValueObject>();
break;
}
}
classes
public class RandomProperties
{
public ValueObject ValueObjectType { get; set; }
public ValueObject ValueObjectTypeId { get; set; }
public ValueInt ValueInt { get; set; }
public ValueString ValueString { get; set; }
}
public class ValueInt
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("value")]
public int value { get; set; }
}
public class ValueString
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("value")]
public string value { get; set; }
}
public class ValueObject
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("value")]
public ValueOfObject value { get; set; }
}
public class ValueOfObject
{
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("currency")]
public string Currency { get; set; }
[JsonProperty("amount")]
public int? Amount { get; set; }
[JsonProperty("typeId")]
public string TypeId { get; set; }
[JsonProperty("id")]
public string ValueId { get; set; }
}