Home > Software engineering >  I can't deserialize the JSON
I can't deserialize the JSON

Time:08-22

I'm trying to connect to the PostNL API Timeframes. The problem is that I keep getting the following exception. I think I got my models correctly but I can't seem to find out what's wrong with it.

Exception:

Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[PostNL.Api.Dtos.TimeFrameHolderDto]' 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) 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. Path 'Timeframes.Timeframe', line 3, position 16. at PostNL.Api.Tests.Unit.Tests.Unit.TimeFramesTests.TimeFrameResponseJsonTests.JsonConvertTests(String filePath) in C:\Git\PostNL.Api.Tests.Unit\TimeFramesTests\TimeFrameResponseJsonTests.cs:line 37

If I read the error I need to create some more models with holders and lists like I did as below but I'm still getting this exception. Does anyone know what I'm doing wrong?

requests/1.json file:

{
  "Timeframes": {
    "Timeframe": [
      {
        "Date": "22-08-2022",
        "Timeframes": {
          "TimeframeTimeFrame": [
            {
              "From": "08:45:00",
              "Options": {
                "string": "Daytime"
              },
              "To": "11:15:00"
            },
            {
              "From": "17:30:00",
              "Options": {
                "string": "Evening"
              },
              "To": "22:00:00"
            }
          ]
        }
      },
      {
        "Date": "23-08-2022",
        "Timeframes": {
          "TimeframeTimeFrame": [
            {
              "From": "09:15:00",
              "Options": {
                "string": "Daytime"
              },
              "To": "11:45:00"
            },
            {
              "From": "17:30:00",
              "Options": {
                "string": "Evening"
              },
              "To": "22:00:00"
            }
          ]
        }
      }
    ]
  }
}

The deserialization test:

using PostNL.Api.Dtos;
using Newtonsoft.Json;
using NUnit.Framework;
using System;
using System.IO;

namespace PostNL.Api.Tests.Unit.TimeFramesTests
{
    [TestFixture]
    [Parallelizable(ParallelScope.All)]
    internal class TimeFrameResponseJsonTests
    {
        [Test]
        [TestCase("../../../TimeFramesTests/requests/1.json")]
        public void JsonConvertTests(string filePath)
        {
            var path = AppDomain.CurrentDomain.BaseDirectory;
            var fullFilePath = Path.Combine(path, filePath);
            if (!File.Exists(fullFilePath))
            {
                Assert.Fail("File does not exists");
                return;
            }

            try
            {
                var fileContent = File.ReadAllText(filePath);
                var json = JsonConvert.DeserializeObject<TimeFrameResponseDto>(fileContent);
            }
            catch (Exception exception)
            {
                Assert.Fail(exception.Message);
            }

            Assert.Pass("Successful convert");
        }
    }
}

The models:

using Newtonsoft.Json;
using System.Collections.Generic;

namespace PostNL.Api.Dtos
{
    internal class TimeFrameDto
    {
        [JsonProperty("From")]
        public string From { get; set; }
        [JsonProperty("Options")]
        public OptionDto[] Options { get; set; }
        [JsonProperty("To")]
        public string To { get; set; }
    }

    internal class TimeFrameTimeFrameHolder
    {
        [JsonProperty("TimeframeTimeFrame")]
        public List<TimeFrameDto> TimeFrameTimeFrame { get; set; }
    }

    internal class DayTimeFrameDto
    {
        [JsonProperty("Date")]
        public string Date { get; set; }
        [JsonProperty("Timeframes")]
        public List<TimeFrameTimeFrameHolder> TimeFrameDtos { get; set; }
    }

    internal class TimeFrameHolderDto
    {
        [JsonProperty("Timeframe")]
        public List<DayTimeFrameDto> TimeFrames { get; set; }
    }

    internal class TimeFrameResponseDto : PostNLBaseDto
    {
        [JsonProperty("Timeframes")]
        public List<TimeFrameHolderDto> TimeFrames { get; set; }

        //[JsonProperty("ReasonNoTimeframes")]
        //public List<ReasonNoTimeFrameDto> ReasonNoTimeFrames { get; set; }
    }
}

CodePudding user response:

you need one more class - DataTimeframesDto

TimeFramesResponseDTo timeFramesResponseDTo=JsonConvert.DeserializeObject<TimeFramesResponseDTo>(fileContent);

public partial class TimeFramesResponseDTo
{
    [JsonProperty("Timeframes")]
    public DataTimeframesDto Timeframes { get; set; }
}

public partial class DataTimeframesDto
{
    [JsonProperty("Timeframe")]
    public List<DayTimeFrameDto> Timeframe { get; set; }
}

UPDATE

The rest of my classes it you still can't use yours


public partial class DayTimeFrameDto
{
    [JsonProperty("Date")]
    public string Date { get; set; }

    [JsonProperty("Timeframes")]
    public TimeFrameTimeFrameHolder Timeframes { get; set; }
}

public partial class TimeFrameTimeFrameHolder
{
    [JsonProperty("TimeframeTimeFrame")]
    public List<TimeframeDTo> TimeFrameTimeFrame{ get; set; }
}

public partial class TimeframeDTo
{
    [JsonProperty("From")]
    public DateTime From { get; set; }

    [JsonProperty("Options")]
    public OptionsDto Options { get; set; }

    [JsonProperty("To")]
    public DateTime To { get; set; }
}

public partial class OptionsDto
{
    [JsonProperty("string")]
    public string OptionsString { get; set; }
}
  • Related