I have a class I use for configuration that holds a 3 tuple of all integers.
public class Configuration
{
public List<Tuple<int, int, int>> MyThreeTuple { get; set; }
public Configuration()
{
MyThreeTuple = new List<Tuple<int, int, int>>();
MyThreeTuple.Add(new Tuple<int, int, int>(-100, 20, 501));
MyThreeTuple.Add(new Tuple<int, int, int>(100, 20, 864));
MyThreeTuple.Add(new Tuple<int, int, int>(500, 20, 1286));
}
}
This class is serialized into Json with System.Web.Script.Serialization
as such
JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
String configJson = jsonSerializer.Serialize(config);
File.WriteAllText(configPath, configJson);
and then deserialized when the application is launched
String configJson = File.ReadAllText(configPath);
JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
object jsonObject = jsonSerializer.Deserialize(configJson, typeof(ApplicationConfiguration));
appConfig = (Configuration)jsonObject;
My issue is that whenever I go to deserialize the Json an exception is thrown
System.MissingMethodException in System.Web.Extensions.dll
With the message
No parameterless constructor defined for type of `System.Tuple`3 ....
This is what the produced Json for the tuple looks like
"MyThreeTuple":
[
{"Item1":-100,"Item2":20,"Item3":501},
{"Item1":100,"Item2":20,"Item3":864},
{"Item1":500,"Item2":20,"Item3":1286}
]
Any idea how to solve this problem?
EDIT:
As other have suggested I tried out JSon.NET and it seems to work to deserialize the json. Though I have found an odd quirk.
So the constructor for my Configuration
class fills in default values for the configuration. Specifically what is given in the code above. I have found that I can serialize the configuration with different values, but when deserialized, the default values are also loaded to the List<Tuple<>>
.
I assume the Json.Net gets around the issue of Tuple
not having a parameterless constructor by first instantiating Configuration
and then setting its values.
It seems to be instantiating the class, then List.Add
ing the Tuple
s it finds in the json to the list. Instead of clearing the list then adding what it finds.
Is there an option in JSon.Net to solve this issue?
The reason why you got this error because JavascriptSerializer requires a public parameter-less constructor which is not the case for Tuple because it's an immutable
take a look here http://json.codeplex.com/ for full comparison between javascriptserializer and json.net
Even microsoft states in the documentation
Json.NET should be used serialization and deserialization. Provides serialization and deserialization functionality for AJAX-enabled applications.
here an example on how you can easily use JsonConvert
to achieve this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
namespace ConsoleApplication25
{
class Program
{
static void Main(string[] args)
{
Configuration configuration = new Configuration();
string configJson = JsonConvert.SerializeObject(configuration);
File.WriteAllText(configPath, configJson);
//Deserialize the content after you read your file in string
var configurationDeserialized = JsonConvert.DeserializeObject<Configuration>(configJson);
}
}
}
public class Configuration
{
[JsonIgnore]
public List<Tuple<int, int, int>> MyThreeTuple { get; set; }
public Configuration()
{
MyThreeTuple = new List<Tuple<int, int, int>>();
MyThreeTuple.Add(new Tuple<int, int, int>(-100, 20, 501));
MyThreeTuple.Add(new Tuple<int, int, int>(100, 20, 864));
MyThreeTuple.Add(new Tuple<int, int, int>(500, 20, 1286));
}
}