Often APIs will have actions where one of the parameters can be either a single object or an array of objects, in order to correctly serialize objects to JSON which can be accepted by the API a custom JsonConverter is needed.

This code is borrowed from this stack overflow article.

public class SingleOrArrayConverter<T> : JsonConverter
{
	public override bool CanConvert(Type objectType)
	{
		return (objectType == typeof(List<T>));
	}
	
	public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
	{
		JToken token = JToken.Load(reader);
		
		if (token.Type == JTokenType.Array)
		{
			return token.ToObject<List<T>>();
		}
		
		return new List<T> { token.ToObject<T>() };
	}
	
	public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
	{
		List<T> list = (List<T>)value;
		
		if (list.Count == 1)
		{
			value = list[0];
		}
		
		serializer.Serialize(writer, value);
	}
	
	public override bool CanWrite
	{
		get { return true; }
	}
}

For example, where “category” can either be a string or an array of strings.

[
	{
		"email": "john.doe@sendgrid.com",
		"timestamp": 1337966815,
		"category": [
			"newuser",
			"transactional"
		],
		"event": "open"
	},
	{
		"email": "jane.doe@sendgrid.com",
		"timestamp": 1337966815,
		"category": "olduser",
		"event": "open"
	}
]

This can be represented by the following class.

class Item
{
	[JsonProperty("email")]
	public string Email { get; set; }
	
	[JsonProperty("timestamp")]
	public int Timestamp { get; set; }
	
	[JsonProperty("event")]
	public string Event { get; set; }
	
	[JsonProperty("category")]
	[JsonConverter(typeof(SingleOrArrayConverter<string>))]
	public List<string> Categories { get; set; }
}

0 Comments

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *