2

I am having an issue with deserializing decimal value correctly. A suggestion on the site was to use a constructor but it is not calling that constructor.

Here is the JSON:

{
    "errors": false,
    "response": {
        "entities": [
        {
            "currency_id": "1",
            "balance": 1e-8,
            "address": ""
        },
        {
            "currency_id": "2",
            "balance": 0,
            "address": null
        },
        {
            "currency_id": "3",
            "balance": 0.09865566,
            "address": null
        },
        {
            "currency_id": "5",
            "balance": 0,
            "address": null
        },
        {
            "currency_id": "6",
            "balance": 0,
            "address": null
        }]
    },
    "pagination": {
        "items_per_page": 100,
        "total_items": 5,
        "current_page": 1,
        "total_pages": 1
   }
}

My classes:

public class ApiResponse<T> where T : class
{
    public bool Errors { get; set; }
    public T Response { get; set; }
}

public class ApiPagingResponse<T> : ApiResponse<T> where T : class
{
    public Pagination Pagination { get; set; }
}

public class GetBalanceListResponse
{
    public GetBalanceListResponseEntity Entity { get; set; }
}

[JsonObject]
public class GetBalanceListResponseEntity
{

    [JsonConstructor]
    public GetBalanceListResponseEntity([JsonProperty("currency_id")]string currencyId, [JsonProperty("balance")]string balance, [JsonProperty("address")]string address)
    {
        CurrencyId = currencyId;
        Balance = decimal.Parse(balance, NumberStyles.AllowExponent | NumberStyles.AllowDecimalPoint,
            CultureInfo.InvariantCulture);
        Address = address;
    }

    [JsonProperty("currency_id")]
    public string CurrencyId { get; set; }

    [JsonProperty("balance")]
    public decimal Balance { get; set; }

    [JsonProperty("address")]
    public string Address { get; set; }
}

I call it using this:

 var result = JsonConvert.DeserializeObject<ApiPagingResponse<GetBalanceListResponse>>(stringResult);

Where stringResult is the json string I want to deserizalize.

Currently it just returns null for the Entity property of the response. All my other serialization works fine with this method, the problem is with "balance": 1e-8,

Has anyone dealt with a similar issue and can be of assistance with this?

Ronak Vachhani
  • 214
  • 2
  • 14
Armand
  • 9,847
  • 9
  • 42
  • 75
  • 2
    In `GetBalanceListResponse`, `public GetBalanceListResponseEntity Entity { get; set; }` should be `public List Entities { get; set; }`. Sample [fiddle](https://dotnetfiddle.net/FDirUE). Otherwise your code basically works. – dbc Jan 17 '18 at 09:24
  • @dbc now I feel like a complete idiot – Armand Jan 17 '18 at 09:42
  • @dbc if you could add this as an answer I can mark it as accepted, thanks – Armand Jun 28 '18 at 08:28
  • answer added as requested. – dbc Jul 17 '18 at 04:36

1 Answers1

1

Your use of [JsonConstructor] is correct. Your only problem is that, in GetBalanceListResponse, the method

public GetBalanceListResponseEntity Entity { get; set; } 

should be

public List<GetBalanceListResponseEntity> Entities { get; set; }

This is because, in the JSON, the corresponding property response.entities is an array:

{
    "errors": false,
    "response": {
        "entities": [
            // Entity values omitted
        ]
    },
    // Pagination omitted
}

With this fix, the constructor is called and your code basically works. Sample fiddle.

To avoid this sort of problem in the future, you could use an automatic code-generation tool such as http://json2csharp.com/, Paste JSON as Classes or https://jsonutils.com/ to generate appropriate classes from your JSON, then modify as required, e.g. by making the auto-generated types generic.

dbc
  • 104,963
  • 20
  • 228
  • 340