Deserializing UPS API RatingResponse into c# strongly typed object

51 views Asked by At

I'm converting some existing code that used Legacy UPS Rating Soap Services to RESTful Rating API using OAuth 2.0. I've successful authenticated and make a Rating Request. I deserialize the RatingResponse to a strongly typed Ratingresponse Object.

The issue I'm having is with the Ratedpackage object:

UPS API Doc:

RatedPackage (required) - One of: Array of Rate_RatedShipment_RatedPackage (objects) or Rate_RatedShipment_RatedPackage (object)

It appears the SOAP Api always returned RatedPackage[] Array.

Multiple packages work fine, when I make the request for one package, I get a single object while my Strongly typed RatingResponse is expecting an Array of Ratedpackage:

Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'UPSShipping.Ratedpackage[]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly. To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.

What is the best way to handle the RatingRepsonse deserialization into a Strongly typed Array of Ratedpackage?

1

There are 1 answers

0
JClarkCDS On

I was avoiding parsing the json or building the c# object with something like JSObject. After Ian's comment, I started researching the quick way to writing a custom Json converter when I stumbled upon How to handle overflow JSON or use JsonElement or JsonNode in System.Text.Json.

Specifically what I discovered was to change the reference from the Ratedpackage[] to a Dictionary object attributed with [JsonExtensionData] which stores any undefined json properties in a Dictionary and doesn't throw an exception. I can then handle parsing the JsonElement if needed!

For Example in my RatedShipment object where I was having the response conflict:

public class Ratedshipment
{
    public Service Service { get; set; }

    ....

    //UPS Rating returns either Array OR Single Object NOT JUST Array throwing Exception
    //public Ratedpackage[] RatedPackage { get; set; }

    [JsonExtensionData]
    public Dictionary<string, Object> RatedpackageJson { get; set; }

}

The pain about this issue is I didn't need Ratedpackage, so I didn't even need to parse it!