0
votes

Deeserializing json in ASP.NET 5 MVC application using

var tulemus = JsonSerializer.Deserialize<EstoJarelMaksTulemnus>(apiResponse, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });


    public class EstoJarelMaksTulemnus
    {
        public string[] Errors { get; set; }
        public EstoData Data { get; set; }
        public string Mac { get; set; }
    }

    public class EstoData
    {
        public string Id { get; set; }
        public string Status { get; set; }
        public string Purchase_url { get; set; }
        public string Merchant_reference { get; set; }
        public decimal Amount { get; set; }
        public string Currency { get; set; }
        public bool Is_test { get; set; }
        public string Return_url { get; set; }
        public string Notification_url { get; set; }
    }

throws error

System.Text.Json.JsonException: The JSON value could not be converted to Store.Controllers.CheckoutController+EstoData. Path: $.data | LineNumber: 0 | BytePositionInLine: 497. at System.Text.Json.ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(Type propertyType) ...

apiResponse contains single line string:

{"errors":[],"data":"{\"id\":\"iUW3YiDIz5Ahg5eO8hV7d3Cv7SVbZ913\",\"status\":\"CREATED\",\"purchase_url\":\"https:\\\/\\\/user.esto.ee\\\/application\\\/iUW3YiDIz5Ahg5eO8hV7d3Cv7SVbZ913\",\"merchant_reference\":\"158502\",\"amount\":93.95,\"currency\":\"EUR\",\"is_test\":true,\"return_url\":\"http:\\\/\\\/localhost:54274\\\/CheckoutController\\\/EstoJarelmaksOK?tellimus=104742\",\"notification_url\":\"http:\\\/\\\/localhost:54274\\\/CheckoutController\\\/EstoJarelmaksTeade?tellimus=104742\"}","mac":"E9C3E61FC347D80200F542C43ABDCF464D537C37A609EC878F95B5F526271A2287F2D2E507B5A14FA3AF5F7A6D4CDECB6E8A1DBDF9A5633E0B3AD96DA35FA1C9"}

postion 497 seems pointt to end of Data property before "mac" property.

How to deserialize this json ?

2
Are you able to change the type of EstoData Data to a string or have another class? Or do you need to only keep one class?Ermiya Eskandary

2 Answers

0
votes

the Data in apiResponse is not an object, it's a string , you can convert the string into a model using Newtonsoft Json.Net , as is explained in this issue : Deserializing stringified (quote enclosed) nested objects with Newtonsoft Json.Net

0
votes

You need to create a custom JsonConverter to be able to correctly deserialise the nested Data JSON object.

This should work: StringToEstoDataConverter.cs

public class StringToEstoDataConverter : JsonConverter<EstoData>
{
  public override EstoData? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
  {
      using (var jsonDoc = JsonDocument.ParseValue(ref reader))
      {
          var infoData = jsonDoc.RootElement.GetString();
          if (infoData != null)
              return JsonSerializer.Deserialize<EstoData>(infoData, options);
      }

      return default;
  }

  public override void Write(Utf8JsonWriter writer, EstoData value, JsonSerializerOptions options)
  {
      throw new NotImplementedException();
  }
}

EstoJarelMaksTulemnus.cs

public class EstoJarelMaksTulemnus
{
  public string[] Errors { get; set; }

  [JsonConverter(typeof(StringToEstoDataConverter))]
  public EstoData Data { get; set; }

  public string Mac { get; set; }
}

Usage:

var tulemus = JsonSerializer.Deserialize<EstoJarelMaksTulemnus>(apiResponse, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });

Here's a working demo:

public class Program
{
  public static void Main()
  {
      var data =
          "{\"errors\":[],\"data\":\"{\\\"id\\\":\\\"iUW3YiDIz5Ahg5eO8hV7d3Cv7SVbZ913\\\",\\\"status\\\":\\\"CREATED\\\",\\\"purchase_url\\\":\\\"https:\\\\\\/\\\\\\/user.esto.ee\\\\\\/application\\\\\\/iUW3YiDIz5Ahg5eO8hV7d3Cv7SVbZ913\\\",\\\"merchant_reference\\\":\\\"158502\\\",\\\"amount\\\":93.95,\\\"currency\\\":\\\"EUR\\\",\\\"is_test\\\":true,\\\"return_url\\\":\\\"http:\\\\\\/\\\\\\/localhost:54274\\\\\\/CheckoutController\\\\\\/EstoJarelmaksOK?tellimus=104742\\\",\\\"notification_url\\\":\\\"http:\\\\\\/\\\\\\/localhost:54274\\\\\\/CheckoutController\\\\\\/EstoJarelmaksTeade?tellimus=104742\\\"}\",\"mac\":\"E9C3E61FC347D80200F542C43ABDCF464D537C37A609EC878F95B5F526271A2287F2D2E507B5A14FA3AF5F7A6D4CDECB6E8A1DBDF9A5633E0B3AD96DA35FA1C9\"}";


      var tulemus = JsonSerializer.Deserialize<EstoJarelMaksTulemnus>(data, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });

      Console.WriteLine(tulemus.Errors.Length);
      Console.WriteLine(tulemus.Data.Id);
      Console.WriteLine(tulemus.Data.Status);
      Console.WriteLine(tulemus.Data.Purchase_url);
      Console.WriteLine(tulemus.Data.Merchant_reference);
      Console.WriteLine(tulemus.Data.Amount);
      Console.WriteLine(tulemus.Data.Currency);
      Console.WriteLine(tulemus.Data.Is_test);
      Console.WriteLine(tulemus.Data.Return_url);
      Console.WriteLine(tulemus.Data.Notification_url);
      Console.WriteLine(tulemus.Mac);
  }
}

public class StringToEstoDataConverter : JsonConverter<EstoData>
{
  public override EstoData? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
  {
      using (var jsonDoc = JsonDocument.ParseValue(ref reader))
      {
          var infoData = jsonDoc.RootElement.GetString();
          if (infoData != null)
              return JsonSerializer.Deserialize<EstoData>(infoData, options);
      }

      return default;
  }

  public override void Write(Utf8JsonWriter writer, EstoData value, JsonSerializerOptions options)
  {
      throw new NotImplementedException();
  }
}


public class EstoJarelMaksTulemnus
{
  public string[] Errors { get; set; }

  [JsonConverter(typeof(StringToEstoDataConverter))]
  public EstoData Data { get; set; }

  public string Mac { get; set; }
}

public class EstoData
{
  public string Id { get; set; }
  public string Status { get; set; }
  public string Purchase_url { get; set; }
  public string Merchant_reference { get; set; }
  public decimal Amount { get; set; }
  public string Currency { get; set; }
  public bool Is_test { get; set; }
  public string Return_url { get; set; }
  public string Notification_url { get; set; }
}

Output:

0
iUW3YiDIz5Ahg5eO8hV7d3Cv7SVbZ913
CREATED
https://user.esto.ee/application/iUW3YiDIz5Ahg5eO8hV7d3Cv7SVbZ913
158502
93.95
EUR
True
http://localhost:54274/CheckoutController/EstoJarelmaksOK?tellimus=104742
http://localhost:54274/CheckoutController/EstoJarelmaksTeade?tellimus=104742
E9C3E61FC347D80200F542C43ABDCF464D537C37A609EC878F95B5F526271A2287F2D2E507B5A14FA3AF5F7A6D4CDECB6E8A1DBDF9A5633E0B3AD96DA35FA1C9