简体   繁体   中英

C# deserailize json in non standard format

I am consuming a web service that will calculate tax. The problem is I don't always get the data back in exactly the same formatn (see example below). When I deserialize the data my code throws an exception. Any tips on what I can do to allow the deserialization to handle a single element or an array of a single element? FYI, I get back a lot more data in addition to the tax, but I am only showing the tax part to keep it simple.

Sometimes I get the data like this:

{
    "data": {
        "tax": [{
            "amount": 0.00,
            "category": 0.0
        }]
    }
}

Sometimes I get it like this:

{
    "data": {
        "tax": {
            "amount": 336.01,
            "category": 0.0
        }
    }
}

Here is my class:

public class Tax
{
    public float amount { get; set; }
    public float category{ get; set; }
}

I am thinking about adding an [XmlIgnore] attribute and manually deserailizing to get the tax data, but I would like to stay away from that if possible.

Make two (or more) different classes, then use the one that doesn't throw an exception when you deseralize.

It looks like you could deseralize the array data using this class:

public class data
{
    public Dictionary<string, double> tax { get; set; }
}

If that class successfully deserializes, you can then copy it over to the tax class, either manually, or by using Reflection .

Not sure how XmlIgnore would help with your JSON serialization, but i would suggest using Newtonsoft.Json to deserialize your payload to JObject. Then you can use Linq to JSON to investigate the result and perhaps manually instantiate your own object based on the type of "tax" property (JArray or JObject)

see LINQ to JSON for more info.

I'd use JSON.Net (link to nuget) . Then I'd get a JObject from JObject.Parse method and check whether the relevant child element is JObject or JArray . Then, I'd convert it to your data class (or a dynamic type)

dynamic taxData;
var json = JObject.Parse(response);
var rawTaxData = json["data"]["tax"];

if (rawTaxData is JObject)
{
    taxData = JsonConvert.DeserializeObject(rawTaxData);
}
else if (rawTaxData is JArray)
{
    var actualData = rawTaxData [0];
    taxData = JsonConvert.DeserializeObject(actualData);
}

Also, just to be sure that your server actually returned data and not, for example, error message, use TryGetValue :

JToken dataToken;
if (!json.TryGetValue("data", out dataToken))
{
    var rawTaxData = dataToken["tax"];
    // ...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM