I have a JSON object where all properties are arrays regardless of if they really should be or not.
{
"StringValue": ["mystringvalue"],
"StringArrayValue": ["value1","value2"],
"LongValue": [123]
}
Meanwhile, my class knows the types they should actually be
class MyClass {
public string StringValue {get;set;}
public string[] StringArrayValue {get;set;}
public long LongValue {get;set;}
}
When I do JsonSerializer.Deserialize(jsondoc), it fails because it cannot convert the arrays to non-arrays. How can I have the deserializer pick the first value in the returned JSON data if the class type is not an array?
CodePudding user response:
If you don't want to make things too complex, you can make an additional class for the Deserialization
class MyClassOriginalValue {
public string[] StringValue {get;set;}
public string[] StringArrayValue {get;set;}
public long[] LongValue {get;set;}
public MyClass GetMyClass()
{
return new MyClass
{
StringValue = this.StringValue?.FirstOrDefault(),
StringArrayValue = this.StringArrayValue,
LongValue = this.LongValue?.FirstOrDefault() ?? 0
}
}
}
Here my results:
void Main()
{
var jsonOrig = $"{{"
"\"StringValue\": [\"mystringvalue\"],"
"\"StringArrayValue\": [\"value1\",\"value2\"],"
"\"LongValue\": [123]"
"}";
var originalJsonValue = JsonSerializer.Deserialize<MyClassOriginalValue>(jsonOrig);
var targetValue = originalJsonValue.GetMyClass();
Console.WriteLine(JsonSerializer.Serialize(targetValue));
}
CodePudding user response:
One approach would be to map the array values to a backing store that is an array, but add a getter-setter adapter that allows you to use the singular StringValue
and LongValue
properties transparently. The "original" singular get-set properties themselves will be ignored by Json per [JsonIgnore]
attribute.
class MyClass
{
[JsonPropertyName("StringValue")]
public string[] StringValueBackingStore { get; set; } = new string[1];
[JsonIgnore]
public string StringValue
{
get => StringValueBackingStore.FirstOrDefault();
set
{
if(StringValueBackingStore.Length == 1)
{
StringValueBackingStore[0] = value;
}
else
{
Debug.Assert(false, "Expecting array length of 1");
}
}
}
public string[] StringArrayValue { get; set; }
[JsonPropertyName("LongValue")]
public long[] LongValueBackingStore { get; set; } = new long[1];
[JsonIgnore]
public long LongValue
{
get => LongValueBackingStore.FirstOrDefault();
set
{
if (LongValueBackingStore.Length == 1)
{
LongValueBackingStore[0] = value;
}
else
{
Debug.Assert(false, "Expecting array length of 1");
}
}
}
}
TEST SERDES
static void Main(string[] args)
{
var myClass = JsonSerializer.Deserialize<MyClass>(jsondoc);
Console.WriteLine($"{myClass.StringValue} {myClass.LongValue} {string.Join(",", myClass.StringArrayValue)}");
Console.WriteLine($"\n{JsonSerializer.Serialize(myClass)}");
}