2

If I attempt to deserialize a series of classes with a root class that's derived from List or Dictionary, I get this exception:

"The value \"System.Collections.Generic.Dictionary`2[System.String,System.Object]\" is not of type \"JSONTesting.UserInformation\" and cannot be used in this generic collection.\r\nParameter name: value"

This is the code that I'm using to create the JSON file and to deserialize it. It's just a small sample project that demonstrates the issue:

    private void BuildUserInfo(object sender, EventArgs e)
    {
      Users users = new Users();
      UserInformation userInformation;

      //Item 1
      userInformation = new UserInformation();
      userInformation.Name = "John Doe";
      userInformation.Age = "50";
      userInformation.Addresses.Add(new Address("11234 Smith Pl.", "Orlando", "FL", "32789"));
      userInformation.Addresses.Add(new Address("553 Park St.", "Boston", "MA", "02115"));
      userInformation.PhoneNumbers.Add(new PhoneNumber("617", "111-2222", string.Empty));
      userInformation.PhoneNumbers.Add(new PhoneNumber("508", "236-0173", "22734"));
      users.Add(userInformation);

      //Serialize
      JavaScriptSerializer serializer = new JavaScriptSerializer();
      StreamWriter streamOut = null;
      string outString = string.Empty;

      outString = serializer.Serialize(users);
      streamOut = new StreamWriter("OUTFILE.JSON");
      streamOut.Write(outString);

      streamOut.Close();
    }

    private void ReadUserInfo(object sender, EventArgs e)
    {
      JavaScriptSerializer serializer;
      StreamReader streamIn = null;
      Users retrievedUsers = null;

      if (File.Exists("OUTFILE.JSON"))
      {
        streamIn = new StreamReader("OUTFILE.JSON");
        serializer = new JavaScriptSerializer();
        retrievedUsers = serializer.Deserialize<Users>(streamIn.ReadToEnd());

        streamIn.Close();
      }
    }
  }

  public class Users: List<UserInformation>
  {
    public UserInformation getUserByName(string name)
    {
      foreach (UserInformation user in this)
      {
        if (name == user.Name)
          return user;
      }

      return null;
    }
  }

  public class UserInformation
  {
    public string Name;
    public string Age;

    public List<Address> Addresses;
    public List<PhoneNumber> PhoneNumbers;

    public UserInformation()
    {
      Name = string.Empty;
      Age = string.Empty;
      Addresses = new List<Address>();
      PhoneNumbers = new List<PhoneNumber>();
    }

    public UserInformation(string Name, string Age)
    {
      this.Name = Name;
      this.Age = Age;
      Addresses = new List<Address>();
      PhoneNumbers = new List<PhoneNumber>();
    }
  }

  public class Address
  {
    public string Street;
    public string City;
    public string State;
    public string PostalCode;

    public Address()
    {
      Street = string.Empty;
      City = string.Empty;
      State = string.Empty;
      PostalCode = string.Empty;
    }

    public Address(string Street, string City, string State, string PostalCode)
    {
      this.Street = Street;
      this.City = City;
      this.State = State;
      this.PostalCode = PostalCode;
    }
  }

  public class PhoneNumber
  {
    public string AreaCode;
    public string Number;
    public string Extension;

    public PhoneNumber()
    {
      AreaCode = string.Empty;
      Number = string.Empty;
      Extension = string.Empty;
    }

    public PhoneNumber(string AreaCode, string Number, string Extension)
    {
      this.AreaCode = AreaCode;
      this.Number = Number;
      this.Extension = Extension;
    }
  }

This is the JSON that is generated by the BuildUserInfo function:

    [
      {
        "Name": "John Doe",
        "Age": "50",
        "Addresses": [
          {
            "Street": "11234 Smith Pl.",
            "City": "Orlando",
            "State": "FL",
            "PostalCode": "32789"
          },
          {
            "Street": "553 Park St.",
            "City": "Boston",
            "State": "MA",
            "PostalCode": "02115"
          }
        ],
        "PhoneNumbers": [
          {
            "AreaCode": "617",
            "Number": "111-2222",
            "Extension": ""
          },
          {
            "AreaCode": "508",
            "Number": "236-0173",
            "Extension": "22734"
          }
        ]
      }
    ]

If I change the Users class so that it is not derived from List and just make it a class with an internal List collection, it works fine. An example of this:

public class Users
{
  public List<UserInformation> UserItems = new List<UserInformation>();
}

What do I need to change to be able to deserialize this JSON?

Edit: Trying the link from the comment below, I changed to the following:

public class Users(IEnumerable<UserInformation> collection) : base (collection) {

}

I get build errors:

Error 1 Invalid token '(' in class, struct, or interface member declaration c:\Local .NET Projects\2010\JSONTesting1\Form1.cs 66 25 JSONTesting1 Error 2 { expected c:\Local .NET Projects\2010\JSONTesting1\Form1.cs 66 25 JSONTesting1 Error 3 ; expected c:\Local .NET Projects\2010\JSONTesting1\Form1.cs 66 69 JSONTesting1 Error 4 Invalid token ')' in class, struct, or interface member declaration c:\Local .NET Projects\2010\JSONTesting1\Form1.cs 66 93 JSONTesting1 Error 5 } expected c:\Local .NET Projects\2010\JSONTesting1\Form1.cs 153 2 JSONTesting1

3
  • stackoverflow.com/questions/5096272/… Commented Feb 26, 2019 at 16:05
  • It didn't work. I added more information to my post. Commented Feb 26, 2019 at 16:19
  • Your trying to put a JSON array into a single object. Try changing the retrievedUsers to a list and then deserialize as a list List<Users> retrievedUsers = new List<Users>(); retrievedUsers = serializer.Deserialize<IList<Users>>streamIn.ReadToEnd()); Commented Feb 26, 2019 at 16:33

1 Answer 1

1

Do you have to use JavaScriptSerializer? If you do, there must some configuration detail we are missing, but Newtonsoft.Json handles the situation without any adjustments:

private static void BuildUserInfo()
{
    // ...

    //Serialize
    File.WriteAllText("OUTFILE.JSON", Newtonsoft.Json.JsonConvert.SerializeObject(users));
}

private static void ReadUserInfo()
{
    Users retrievedUsers = null;

    if (File.Exists("OUTFILE.JSON"))
    {
        var json = File.ReadAllText("OUTFILE.JSON");

        retrievedUsers = Newtonsoft.Json.JsonConvert.DeserializeObject<Users>(json);
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

I am serializing it exactly as I want it to be - the entire collection out to a JSON file. I want to deserialize it into a Users object, which is a collection of UserInformation objects. I want to bring the entire thing back into a Users object. If I change the Users class so that it is not derived from List<UserInformat>, it works fine.
Editted the answer, using Newtonsoft.Json

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.