user142617
user142617

Reputation: 386

c# Newtonsoft.Json DeserializeObject error

I am trying to deserialise the following json object but getting an error, all I would like to do is put the json into a c# List:

public class CardTextModel
{
    public string prod_Code { get; set; }
    public string page1Text { get; set; }
    public string insideText { get; set; }
    public string userName { get; set; }
    public Nullable<System.DateTime> exportDate { get; set; }
    public List<CardTextModel> card_Text { get; set; }
}

Here is where I try to deserialise the json

class Program
{
    static void Main(string[] args)
    {
        try
        {
            var content = @"{
              ""card_Text"": [
                {
                  ""prod_Code"": ""G01Q0320WS"",
                  ""page1Text"": ""SHORTY SET SZ 10"",
                  ""insideText"": ""SHORTY SET SZ 10"",
                  ""userName"": ""daz"",
                  ""exportDate"": null
                },
                {
                  ""prod_Code"": ""G01Q0380"",
                  ""page1Text"": ""TREE DECS SET 4 RESIN"",
                  ""insideText"": ""TREE DECS SET 4 RESIN"",
                  ""userName"": ""mark"",
                  ""exportDate"": null
                }
              ]
            }";

            var model = JsonConvert.DeserializeObject<List<CardTextModel>>(content);
        }
        catch (Exception ex)
        {

        }
    }
}

I am getting the following error when I try to deserize my json object

Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[CardTextModel]' 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 'card_Text', line 2, position 30.

I am using Newtonsoft.Json 9.0.0.0

Thanks for any help

Upvotes: 0

Views: 12252

Answers (6)

feor
feor

Reputation: 1

Not sure(no time to check) but Hope it helps. Try to:

using System.Runtime.Serialization;
using System.Collections.Generic;
using System.Runtime.Serialization.Json;
...
[DataContract]
public class CardText
{ 
    [DataMember]
    public string prod_Code { get; set; }
    [DataMember]
    public string page1Text { get; set; }
    [DataMember]
    public string insideText { get; set; }
    [DataMember]
    public string userName { get; set; }
    [DataMember]
    public object exportDate { get; set; }
} 

[DataContract]
public class CardTextRootObject
{
    [DataMember]
    public List<CardText> card_Text { get; set; }
}
...
    private T parseJSON<T>(string content)
    {
        using (MemoryStream stream = new MemoryStream())
        {
            using (StreamWriter writer = new StreamWriter(stream))
            {
                writer.Write(content);
                writer.Flush();
                stream.Position = 0;

                DataContractJsonSerializer JSONSer = new DataContractJsonSerializer(typeof(T));

                return (T)JSONSer.ReadObject(stream);
            }
        }
    }

...
var deserializedJSONobj = parseJSON<CardTextRootObject>(content);
...

Realy hope it helps)).

Upvotes: 0

Kent Aguilar
Kent Aguilar

Reputation: 5338

To further understand the process flow, you may opt to test the compatibility of your object to the actual JSON conversion. Try generating the JSON string from a list of "CardTextModel" objects.

var cardList = new List<CardTextModel>(){
    new CardTextModel{ 
        prod_Code = "G01Q0320WS",
        page1Text = "SHORTY SET SZ 10",
        insideText = "SHORTY SET SZ 10",
        userName = "daz",
        exportDate = null
    },
    new CardTextModel{ 
        prod_Code = "G01Q0380",
        page1Text = "TREE DECS SET 4 RESIN",
        insideText = "TREE DECS SET 4 RESIN",
        userName = "mark",
        exportDate = null
    },
};

string output = JsonConvert.SerializeObject(cardList);

The output would be:

"[{\"prod_Code\":\"G01Q0320WS\",\"page1Text\":\"SHORTY SET SZ 10\",\"insideText\":\"SHORTY SET SZ 10\",\"userName\":\"daz\",\"exportDate\":null},{\"prod_Code\":\"G01Q0380\",\"page1Text\":\"TREE DECS SET 4 RESIN\",\"insideText\":\"TREE DECS SET 4 RESIN\",\"userName\":\"mark\",\"exportDate\":null}]"

Hence, we could now use the output as basis. Going back to your question, here's the actual code.

class Program
    {
        static void Main(string[] args)
        {
            var content = "[{\"prod_Code\":\"G01Q0320WS\",\"page1Text\":\"SHORTY SET SZ 10\",\"insideText\":\"SHORTY SET SZ 10\",\"userName\":\"daz\",\"exportDate\":null},{\"prod_Code\":\"G01Q0380\",\"page1Text\":\"TREE DECS SET 4 RESIN\",\"insideText\":\"TREE DECS SET 4 RESIN\",\"userName\":\"mark\",\"exportDate\":null}]";

            var model = JsonConvert.DeserializeObject<List<CardTextModel>>(content);
        }
    }

The value of model should be:

enter image description here

Hope this helps! :)

Upvotes: 0

Mick Walker
Mick Walker

Reputation: 3847

Your JSON is not an array, it is an object which has a poperty called "card_Text" which is an array. Try this:

 public class CardsModel
    {
        public List<CardTextModel> card_Text { get; set; }
    }
    public class CardTextModel
    {
        public string prod_Code { get; set; }
        public string page1Text { get; set; }
        public string insideText { get; set; }
        public string userName { get; set; }
        public Nullable<System.DateTime> exportDate { get; set; }
        public List<CardTextModel> card_Text { get; set; }
    }


var model = JsonConvert.DeserializeObject<CardsModel>(content);

Upvotes: 0

Misza
Misza

Reputation: 665

Your content is not an array but a JSON object that contains one field "card_Text", which contains the array you're looking for.

Either modify the type parameter of DeserializeObject to be a class such as

class CardTextWrapperModel
{
    public List<CardTextModel> card_Text { get; set; }
}

or pass the array directly without the outer object:

var content = @"[
            {
              ""prod_Code"": ""G01Q0320WS"",
              ""page1Text"": ""SHORTY SET SZ 10"",
              ""insideText"": ""SHORTY SET SZ 10"",
              ""userName"": ""daz"",
              ""exportDate"": null
            },
            {
              ""prod_Code"": ""G01Q0380"",
              ""page1Text"": ""TREE DECS SET 4 RESIN"",
              ""insideText"": ""TREE DECS SET 4 RESIN"",
              ""userName"": ""mark"",
              ""exportDate"": null
            }
          ]";

Upvotes: 0

Igor
Igor

Reputation: 62213

Its because in your json you have a property card_Text which is assigned to the array. Either modify your json or add a stub class that does the same.


Modified code

public class ModelHolder{
    public List<CardTextModel> card_Text {get;set;}
}

In your deserialization code

var model = JsonConvert.DeserializeObject<ModelHolder>(content);

Modified json

var content = @"[
    {
      ""prod_Code"": ""G01Q0320WS"",
      ""page1Text"": ""SHORTY SET SZ 10"",
      ""insideText"": ""SHORTY SET SZ 10"",
      ""userName"": ""daz"",
      ""exportDate"": null
    },
    {
      ""prod_Code"": ""G01Q0380"",
      ""page1Text"": ""TREE DECS SET 4 RESIN"",
      ""insideText"": ""TREE DECS SET 4 RESIN"",
      ""userName"": ""mark"",
      ""exportDate"": null
    }
  ]";

Upvotes: 1

Amir Popovich
Amir Popovich

Reputation: 29836

Your json should look like:

var content = @"[
                {
                  ""prod_Code"": ""G01Q0320WS"",
                  ""page1Text"": ""SHORTY SET SZ 10"",
                  ""insideText"": ""SHORTY SET SZ 10"",
                  ""userName"": ""daz"",
                  ""exportDate"": null
                },
                {
                  ""prod_Code"": ""G01Q0380"",
                  ""page1Text"": ""TREE DECS SET 4 RESIN"",
                  ""insideText"": ""TREE DECS SET 4 RESIN"",
                  ""userName"": ""mark"",
                  ""exportDate"": null
                }
              ]";

var model = JsonConvert.DeserializeObject<List<CardTextModel>>(content);

Or your object needs to change to support the root element card_Text.

public class CardTextModel
{
    public string prod_Code { get; set; }
    public string page1Text { get; set; }
    public string insideText { get; set; }
    public string userName { get; set; }
    public Nullable<System.DateTime> exportDate { get; set; }
    public List<CardTextModel> card_Text { get; set; }
}

public class CardTextModelRoot
{
    public List<CardTextModel> card_Text {get;set;}
}

var content = @"{
      ""card_Text"": [
        {
          ""prod_Code"": ""G01Q0320WS"",
          ""page1Text"": ""SHORTY SET SZ 10"",
          ""insideText"": ""SHORTY SET SZ 10"",
          ""userName"": ""daz"",
          ""exportDate"": null
        },
        {
          ""prod_Code"": ""G01Q0380"",
          ""page1Text"": ""TREE DECS SET 4 RESIN"",
          ""insideText"": ""TREE DECS SET 4 RESIN"",
          ""userName"": ""mark"",
          ""exportDate"": null
        }
      ]
    }";

var model = JsonConvert.DeserializeObject<CardTextModelRoot>(content);

Upvotes: 2

Related Questions