Reputation: 1478
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
Upvotes: 2
Views: 571
Reputation: 5767
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);
}
}
Upvotes: 1