An API I depend on (that I have no control over) previously took a JSON structure like so:
{
"values": "one, two, three"
}
The API made a backward-breaking change to this payload, and converted the comma-separated values in a string to a JSON array:
{
"values": ["one", "two", "three"]
}
Using Flurl, the way I deserialized this was:
public class Payload
{
public string Values { get; set; } = "";
}
// somewhere else where I make the API call
public async Task<Payload> PutPayload(Payload data)
{
return await "https://theapi.com"
.PutJsonAsync(data)
.ReceiveJson<Payload>();
}
I can no longer use string Values
but use something like List<string> Values
. Here is what I want:
- I want my code to change to use
List<string> Values
for the property in the object. All code will be updated to use this new type. - If I detect the "old" API, I want to convert the
string
->List<string>
(via string split) as transparently as reasonably possible. Basically, I don't want my code knowing about two different types for this object, or two versions of this object.
My path to trying to do this was to inherit a class from JsonConverter<string>
(in the Newtonsoft.Json
package) and apply it to my Payload
class:
internal class ConvertCsvStringToArray : JsonConverter<string>
{
// Implement WriteJson() and ReadJson() somehow
}
public class Payload
{
[JsonConverter(typeof(ConvertCsvStringToArray))]
public List<string> Values { get; set; } = new();
}
First, I don't know if I'm headed in the right direction on this. What gave me pause was that it didn't make sense to create a converter for a string
type, because I feel like that only works when I implement JsonConverter<string>.ReadJson()
. For WriteJson()
, it gives me a string
but really what I need to do is alter how I write List<string>
(it either goes out normally as itself, or I "box" it back into a comma separated list of values as a string.
How can I properly do this? The reason why I liked the JsonConverter
approach is that it gives me that "conversion transparency" I really want (my code won't know it's happening since the conversion logic happens behind the scenes).