I'm trying to fix my SendGridPlus library to deal with SendGrid events, but I'm having some trouble with the inconsistent treatment of categories in the API.
In the following example payload taken from the SendGrid API reference, you'll notice that the category
property for each item can either be a single 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"
}
]
It seems my options to make JSON.NET like this are fixing the string before it comes in, or configuring JSON.NET to accept the incorrect data. I'd rather not do any string parsing if I can get away with it.
Is there any other way I can handle this using Json.Net?
Best Answer
The best way to handle this situation is to use a custom
JsonConverter
.Before we get to the converter, we'll need to define a class to deserialize the data into. For the
Categories
property that can vary between a single item and an array, define it as aList<string>
and mark it with a[JsonConverter]
attribute so that JSON.Net will know to use the custom converter for that property. I would also recommend using[JsonProperty]
attributes so that the member properties can be given meaningful names independent of what is defined in the JSON.Here is how I would implement the converter. Notice I've made the converter generic so that it can be used with strings or other types of objects as needed.
Here is an short program demonstrating the converter in action with your sample data:
And finally, here is the output of the above:
Fiddle: https://dotnetfiddle.net/lERrmu
EDIT
If you need to go the other way, i.e. serialize, while keeping the same format, you can implement the
WriteJson()
method of the converter as shown below. (Be sure to remove theCanWrite
override or change it to returntrue
, or elseWriteJson()
will never be called.)Fiddle: https://dotnetfiddle.net/XG3eRy