-1

I have this JSON object returned from API:

[
  {
    "batchId": 789,
    "debtId": 1841,
    "dateAdded": "2021-07-27T16:01:39.41",
    "debtCategoryId": 2,
    "agreementNumber": 78262155,
    "clientNumber": 1068055,
    "clientName": "Client Two"
  },
  {
    "batchId": 866,
    "debtId": 1918,
    "dateAdded": "2021-08-25T14:47:18.13",
    "debtCategoryId": 2,
    "agreementNumber": 1000140792,
    "clientNumber": 11213287,
    "clientName": "Client One"
  }
]

I'm trying to convert that to a C# object which has this structure:

public class DebtConfirmationResponse
    {
        public List<DebtConfirmation> DebtConfirmations { get; set; }
    }

Where DebtConfirmation has these properties:

public class DebtConfirmation
    {
        public int BatchId { get; set; }
        public int DebtId { get; set; }
        public string DateAdded { get; set; }
        public int DebtCategoryId { get; set; }
        public string AgreementNumber { get; set; } = string.Empty;
        public string ClientNumber { get; set; } = string.Empty;
        public string ClientName { get; set; } = string.Empty;
    }

The error I'm getting is:

the json value could not be converted to the name of the model path $ linenumber 0 bytepositioninline 1

Is there anything wrong with the way how the model is being setup? I also tried converting to the same model with batch id only as a property and I got the same message.

halfer
  • 19,824
  • 17
  • 99
  • 186
Laziale
  • 7,965
  • 46
  • 146
  • 262
  • You define `AgreementNumber `, `ClientNumber ` as strings in your C# code, but this properties is numbers in json, so you have to define it as longs – Georgy Tarasov Dec 24 '21 at 17:39
  • Thanks, I did try only with batchId and I got the same message. Do you think the model hierarchy is correctly set? – Laziale Dec 24 '21 at 17:42

2 Answers2

0

You define AgreementNumber, ClientNumber as strings in your C# code, but this properties is numbers in json, so you have to define it as longs.

And the another point is that you don't need a wrapper around DebtConfirmation class. Deserealize your json into ICollection, IList or just List of DebtConfirmation objects.

I used the quicktype.io for retrieving C# classes from json example you provide. This is very helpful for those who doesn't want to manually generate the models for their JSON strings.

Here is the code sample.

The output is:

789
866
using System.Text.Json;
using System.Text.Json.Serialization;

string json = "[\n  {\n    \"batchId\": 789,\n    \"debtId\": 1841,\n    \"dateAdded\": \"2021-07-27T16:01:39.41\",\n    \"debtCategoryId\": 2,\n    \"agreementNumber\": 78262155,\n    \"clientNumber\": 1068055,\n    \"clientName\": \"Client Two\"\n  },\n  {\n    \"batchId\": 866,\n    \"debtId\": 1918,\n    \"dateAdded\": \"2021-08-25T14:47:18.13\",\n    \"debtCategoryId\": 2,\n    \"agreementNumber\": 1000140792,\n    \"clientNumber\": 11213287,\n    \"clientName\": \"Client One\"\n  }\n]";
var data = JsonSerializer.Deserialize<ICollection<DebtConfirmation>>(json);
foreach (DebtConfirmation current in data)
{
    Console.WriteLine(current.BatchId);
}


public partial class DebtConfirmation 
{
    [JsonPropertyName("batchId")]
    public long BatchId { get; set; }

    [JsonPropertyName("debtId")]
    public long DebtId { get; set; }

    [JsonPropertyName("dateAdded")]
    public DateTimeOffset DateAdded { get; set; }

    [JsonPropertyName("debtCategoryId")]
    public long DebtCategoryId { get; set; }

    [JsonPropertyName("agreementNumber")]
    public long AgreementNumber { get; set; }

    [JsonPropertyName("clientNumber")]
    public long ClientNumber { get; set; }

    [JsonPropertyName("clientName")]
    public string ClientName { get; set; }
}
Georgy Tarasov
  • 1,534
  • 9
  • 11
0

You can use @GeorgyTarasov's answer. But it is definitely not the simplest option.

You can simply use JsonNamingPolicy.CamelCase.

Then you would simply do...

var options = new JsonSerializerOptions
{
    DictionaryKeyPolicy = JsonNamingPolicy.CamelCase,
};
var ret = JsonSerializer.Deserialize<DebtConfirmation>(payload, options);

If you are using AspNet Core, you can register the option here

services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.DictionaryKeyPolicy = JsonNamingPolicy.CamelCase;
    });
Aron
  • 15,464
  • 3
  • 31
  • 64