Deserialize JSON to 2 different models - c#

Does Newtonsoft.JSON library have a simple way I can automatically deserialize JSON into 2 different Models/classes?
For example I get the JSON:
[{
"guardian_id": "1453",
"guardian_name": "Foo Bar",
"patient_id": "938",
"patient_name": "Foo Bar",
}]
And I need de-serialize this to the following models:
class Guardian {
[JsonProperty(PropertyName = "guardian_id")]
public int ID { get; set; }
[JsonProperty(PropertyName = "guardian_name")]
public int Name { get; set; }
}
class Patient {
[JsonProperty(PropertyName = "patient_id")]
public int ID { get; set; }
[JsonProperty(PropertyName = "patient_name")]
public int Name { get; set; }
}
Is there a simple way to deserialize this JSON into 2 Models without having to iterate over the JSON? Maybe JSON property ids will just work?
Pair<Guardian, Patient> pair = JsonConvert.DeserializeObject(response.Content);

First off, your models are slightly incorrect. The name properties need to be strings, instead of integers:
class Guardian
{
[JsonProperty(PropertyName = "guardian_id")]
public int ID { get; set; }
[JsonProperty(PropertyName = "guardian_name")]
public string Name { get; set; } // <-- This
}
class Patient
{
[JsonProperty(PropertyName = "patient_id")]
public int ID { get; set; }
[JsonProperty(PropertyName = "patient_name")]
public string Name { get; set; } // <-- This
}
Once you've corrected that, you can deserialize the JSON string into two lists of different types. In your case, List<Guardian> and List<Patient> respectively:
string json = #"[{'guardian_id':'1453','guardian_name':'Foo Bar','patient_id':'938','patient_name':'Foo Bar'}]";
var guardians = JsonConvert.DeserializeObject<List<Guardian>>(json);
var patients = JsonConvert.DeserializeObject<List<Patient>>(json);

It you want to do it with 1 call, you need to create a class that matches the JSON. That class can then return Guardian and Patient objects as needed. Also you'll need to use an array or list for the return type because the source JSON is an array.
The class to create:
public class Pair
{
public Pair()
{
Guardian = new Guardian();
Patient = new Patient();
}
[JsonIgnore]
public Guardian Guardian { get; set; }
[JsonIgnore]
public Patient Patient { get; set; }
[JsonProperty(PropertyName = "guardian_id")]
public int GuardianID
{
get { return Guardian.ID; }
set { Guardian.ID = value; }
}
[JsonProperty(PropertyName = "guardian_name")]
public string GuardianName
{
get { return Guardian.Name; }
set { Guardian.Name = value; }
}
[JsonProperty(PropertyName = "patient_id")]
public int PatientID
{
get { return Patient.ID; }
set { Patient.ID = value; }
}
[JsonProperty(PropertyName = "patient_name")]
public string PatientName
{
get { return Patient.Name; }
set { Patient.Name = value; }
}
}
And how to use it:
var pairs = JsonConvert.DeserializeObject<Pair[]>(response.Content);
if (pairs.Any())
{
var pair = pairs[0];
Console.WriteLine(pair.Guardian.Name);
Console.WriteLine(pair.Patient.Name);
}

Not in one call, and it seems the data is an array, so you need a little more work.
Zip is the key method here to join the two separate object lists:
Guardian[] guardians = JsonConvert.DeserializeObject<Guardian[]>(response.Content);
Patient[] patients = JsonConvert.DeserializeObject<Patient[]>(response.Content);
var combined = guardians.Zip(patients, (g, p) => Tuple.Create(g, p)).ToList();
It would be far more easier to just read the JSON at once, it a single object.

It can't be done with 1 call with the types that you show. You can try using the generic <T> approach for each type, also you'll need to use arrays or lists for the return type because the source JSON is an array:
var guardians = JsonConvert.DeserializeObject<Guardian[]>(response.Content);
var patients = JsonConvert.DeserializeObject<Patient[]>(response.Content);
And then combine the two if you need them to be paired. E.g. if you are sure that you always have just one of each:
var pair = new Pair(guardians[0], patients[0]);

You could make a type to house the two subobjects:
[JsonConverter(typeof(GuardianPatientConverter))]
class GuardianPatient
{
public Guardian Guardian { get; set; }
public Patient Patient { get; set; }
}
And then create a JSON converter to handle the JSON:
class GuardianPatientConverter : JsonConverter
{
public override bool CanRead
{
get { return true; }
}
public override bool CanWrite
{
get { return false; }
}
public override bool CanConvert(Type objectType)
{
return typeof(GuardianPatient) == objectType;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return null;
}
var jObject = JObject.Load(reader);
var guardian = new Guardian();
var patient = new Patient();
serializer.Populate(jObject.CreateReader(), guardian);
serializer.Populate(jObject.CreateReader(), patient);
return new GuardianPatient()
{
Guardian = guardian,
Patient = patient
};
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
And then you can use it like so:
var json = "[{\"guardian_id\":\"1453\",\"guardian_name\":\"Foo Bar\",\"patient_id\":\"938\",\"patient_name\":\"Foo Bar\",}]";
var objects = JsonConvert.DeserializeObject<IEnumerable<GuardianPatient>>(json);
and if you want it as an array of pairs:
var objects = JsonConvert.DeserializeObject<IEnumerable<GuardianPatient>>(json)
.Select(o => new Pair(o.Guardian, o.Patient))
.ToArray();
This won't make it any faster, but I suspect you're looking for an easier way to work with the JSON.

One another approach would be creating class that matches JSON format, i.e. class with four properties with corresponding names. Then, deserialize JSON into that class and then use it in your code (set properties of objects with values from JSON, pass deserialized object to constructor of another class).

In your models, The name properties need to be strings, instead of integers. After correcting it.
You can use Tuple class
string json = #"[{'guardian_id':'1453','guardian_name':'Foo Bar','patient_id':'938','patient_name':'Foo Bar'}]";
var combination = new Tuple<List<Guardian>, List<Patient>>(JsonConvert.DeserializeObject<List<Guardian>>(json), JsonConvert.DeserializeObject<List<Patient>>(json));

static void Main(string[] args)
{
string json = JsonConvert.SerializeObject(new[]
{
new
{
guardian_id = "1453",
guardian_name = "Foo Bar",
patient_id = "938",
patient_name = "Bar Foo",
}
});
Guardian[] guardians = JsonConvert.DeserializeObject<Guardian[]>(json);
Patient[] patients = JsonConvert.DeserializeObject<Patient[]>(json);
}

Since both your objects are the same, wouldn't it make more sense to just have an ID/Name structure of a single base class? If you need to send all the data at the same time, you can restructure your data and use a data transfer object pattern. The JSON object would become
[{
"guardian": {
"id": "1453",
"name": "Foo Bar"
},
"patient": {
"id" : "938",
"name": "Foo Bar"
}
}]
And your corresponding data objects would be:
public class Record {
public int id { get; set; } // or string. I'm not sure which would be more appropriate
public string name { get; set;}
}
and
public class RecordDto {
public Record guardian { get; set; }
public Record patient { get; set; }
}
And your API would receive a
List<RecordDto>
parameter (since you are passing an array of objects).

Related

Serializing a custom object using SOLID principles

I want to serialize my model objects (from WPF MVVM) which contains pure data. This sounds easy but I don't want to use the Serialization attributes and stuff provided in .NET framework. I just want to serialize it using my own way.
So here's a simplified version of one of my classes.
public class EntryKeyValuePair
{
public EntryKeyValuePair(string key, string value, bool isMultiline = false, bool isMandatory = true, bool isProtected = false)
{
Key = key;
Value = value;
IsMultiline = isMultiline;
IsMandatory = isMandatory;
IsProtected = isProtected;
}
public string Key { get; set; }
public string Value { get; set; }
public bool IsMultiline { get; set; }
public bool IsMandatory { get; set; }
public bool IsProtected { get; set; }
public static EntryKeyValuePair FromXML(XElement element, ICipher cipher)
{
string key = cipher.Decrypt(element.Element(nameof(Key)).Value);
string value = cipher.Decrypt(element.Element(nameof(Value)).Value);
bool isMultiline = bool.Parse(element.Element(nameof(IsMultiline)).Value);
bool isMandatory = bool.Parse(element.Element(nameof(IsMandatory)).Value);
bool isProtected = bool.Parse(element.Element(nameof(IsProtected)).Value);
return new EntryKeyValuePair(key, value, isMultiline, isMandatory, isProtected);
}
public XElement ToXML(ICipher cipher)
{
return new XElement(nameof(EntryKeyValuePair),
new XElement(nameof(Key),cipher.Encrypt(Key)),
new XElement(nameof(Value), cipher.Encrypt(Value)),
new XElement(nameof(IsMultiline), IsMultiline), new XElement(nameof(IsMandatory), IsMandatory),
new XElement(nameof(IsProtected), IsProtected));
}
}
This works quite well. But this violates single responsibility principle and maybe other principles as well. This is also difficult to maintain and extend.
So I wanted to find another way. And here it is:
First I defined an IStringFormatter interface which can format the data to any string data formats like XML and JSON. (Not sure tho)
interface IStringFormatter
{
string Name { get; set; }
Dictionary<string, string> FieldDictionary { get; }
string Format();
}
Here's how the XMLStringFormatter looks like:
class XmlStringFormatter : IStringFormatter
{
public XmlStringFormatter()
{
FieldDictionary = new Dictionary<string, string>();
}
public string Name { get; set; }
public Dictionary<string, string> FieldDictionary { get; }
public string Format()
{
var xElement = new XElement(Name, FieldDictionary.Keys.Select(key => new XElement(key, FieldDictionary[key])));
return xElement.ToString();
}
}
Then I defined an ISerializer to serialize (or rather save) my data objects to the IStringFormatter.
interface ISerializer<T>
{
T DeSerialize(IStringFormatter stringFormatter);
void Serialize(T obj, IStringFormatter stringFormatter);
}
And here is how I "Serialize" EntryKeyValurPair by implementing this:
internal class EntryKeyValurPairSerializer : ISerializer<EntryKeyValuePair>
{
public EntryKeyValuePair DeSerialize(IStringFormatter stringFormatter)
{
Dictionary<string, string> fieldDictionary = stringFormatter.FieldDictionary;
try {
string key = fieldDictionary[nameof(EntryKeyValuePair.Key)];
string value = fieldDictionary[nameof(EntryKeyValuePair.Value)];
bool isMandatory = bool.Parse(fieldDictionary[nameof(EntryKeyValuePair.IsMandatory)]);
bool isProtected = bool.Parse(fieldDictionary[nameof(EntryKeyValuePair.IsProtected)]);
bool isMultiline = bool.Parse(fieldDictionary[nameof(EntryKeyValuePair.IsMultiline)]);
return new EntryKeyValuePair(key, value, isMultiline, isMandatory, isProtected);
}
catch (KeyNotFoundException ex) {
throw new SerializationException(ex);
}
catch (FormatException ex) {
throw new SerializationException(ex);
}
}
public void Serialize(EntryKeyValuePair obj, IStringFormatter stringFormatter)
{
stringFormatter.Name = nameof(EntryKeyValuePair);
Dictionary<string, string> fieldDictionary = stringFormatter.FieldDictionary;
fieldDictionary.Add(nameof(EntryKeyValuePair.Key), obj.Key);
fieldDictionary.Add(nameof(EntryKeyValuePair.Value), obj.Value);
fieldDictionary.Add(nameof(EntryKeyValuePair.IsMandatory), obj.IsMandatory.ToString());
fieldDictionary.Add(nameof(EntryKeyValuePair.IsProtected), obj.IsProtected.ToString());
fieldDictionary.Add(nameof(EntryKeyValuePair.IsMultiline), obj.IsMultiline.ToString());
}
}
Now this works fine. But the problem is when I have a complex type like List<Entry> (where Entry is another data class) in my data classes.
As the IStringFormatter contains a Dictionary<string, string>, I can't just convert a List<Entry> to a string because I don't know what kind of IStringFormatter it wants in the context of ISerializer. How can I fix this? I also want to know if my solution is adhering to SOLID principles. If you can suggest a better solution (NOT the typical .NET serialization), I would appreciate it.
Writing your own serializer might be an interesting task, but I doubt that this is a good idea.
As I understood you want to keep your models clean, without any serialization specific attributes. I guess by "typical .NET serialization" you mean methods included with .Net framework.
For simplicity we will use these simple classes as an example:
class Customer
{
public string Name { get; set; }
public int Age { get; set; }
public List<Order> Orders { get; set; }
}
class Order
{
public int Id { get; set; }
public string Details { get; set; }
}
An easy option would be to use Json.NET:
var customer = new Customer
{
Name = "Darth Vader",
Age = 45,
Orders = new List<Order>
{
new Order { Id = 1, Details = "Order1" },
new Order { Id = 2, Details = "Order2" }
}
};
string json = JsonConvert.SerializeObject(customer);
So as you can see you don't need to add any custom attributes to Customer class. It will work until you want to serialize all public properties.
The resulting JSON will be:
{
"Name": "Darth Vader",
"Age": 45,
"Orders": [
{
"Id": 1,
"Details": "Order1"
},
{
"Id": 2,
"Details": "Order2"
}
]
}
After that you can always deserialize it:
var customer = JsonConvert.DeserializeObject<Customer>(json);
Lets say that you don't want Age property to be included. In this case I would suggest to create a different class that will be used for serialization only:
class CostomerSerializationContract
{
public string Name { get; set; }
public List<Order> Orders { get; set; }
}
This main advantage if this approach is that you have separate class for serialization, and you can add any custom attributes there, if you choose to use some other serializer, without violating SOLID principle. The main disadvantage is that you need to keep both objects in sync manually.
You can use AutoMapper to reduce manual work when creating serialization contract from source class.

Handling Master Data on (De-)Serialization with JSON.net

Using JSON.NET I am stuck on a issue with MasterData with regards to GET and POST operations.
Using the example of a movie, the JSON I could get on a GET operation before deserializing is the following:
{
“movie”: {
“name”:”bad boys”,
”genre”: {
“id”:"1",
”name”:”thriller”
}
}
}
However, on a POST operation I would like to construct a serialized string like the following:
{
“movie”: {
“name”:”bad boys”,
”genre”:"1"
}
}
As you can see, with a GET operation I need to deserialize the complete object, while on serialize for POST I need to add the Id only, but with the same JsonPropertyName.
What is the cleanest way to obtain this situation? I've been trying to work on the IContractResolver and IReferenceResolver, but those both didn't get me there yet. Also have been trying to work with propertynames as the following example:
[JsonProperty(PropertyName = "genre")]
public Genre Genre { get; set; }
[JsonProperty(PropertyName = "genre")]
public string GenreId { get { return Genre != null ? Genre.Id : 0; } }
I've also tried using the ShouldSerialize[MemberName] and ShouldDeserialize[MemberName] situations, but those gave an exception saying I cannot use two properties with the same name, which is logical in a way.
For now, my only idea left is to use a DTO for serialization, but I would rather prefer something more clean than that solution. So open for suggestions!
You can write a Custom converter.
public class GenreConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Genre);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return JObject.Load(reader).ToObject<Genre>();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var genre = value as Genre;
writer.WriteValue(genre.id);
}
}
All you need now is using JsonConverter atttribute
public class Movie
{
public string Name { get; set; }
[JsonConverter(typeof(GenreConverter))]
public Genre Genre { get; set; }
}
Use custom converter for this. You want to check type of genre attribute and read it as object or int.
In my opinion, using a DTO is the cleanest solution. Since your models are different for GET/POST, you ideally require two separate models. I've abused the NullValueHandling.Ignore serializer setting to mean you can use the same model for both situations, providing you don't mind always having the Id property on Genre:
class MovieJsonWrapper
{
[JsonProperty("movie")]
public Movie Movie { get; set; }
}
class Movie
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("genre")]
public Genre Genre { get; set; }
}
class Genre
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
}
We can then use this with:
var movie = new Movie
{
Name = "bad boys",
Genre = new Genre
{
Id = "1"
}
};
var movieJsonWrapper = new MovieJsonWrapper { Movie = movie };
var jsonSerializerSettings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore };
var json = JsonConvert.SerializeObject(movieJsonWrapper, jsonSerializerSettings);
Which would produce the following:
{
"movie": {
"name": "bad boys",
"genre": {
"id": "1"
}
}
}
Similarly, we can then deserialize the GET response with:
var result = JsonConvert.DeserializeObject<MovieJsonWrapper>(raw);
If you really do need to ditch the Id property on the Genre when POSTing, then you would require additional Models. This solution reduces the amount of boilerplate.

Deserialize json to dynamic/anonymous class asp.net

I have one concrete class called ShipFromAddress and where I am deserializing my json this below way
JavaScriptSerializer jss = new JavaScriptSerializer();
oShipFromAddress = jss.Deserialize<ShipFromAddress>(Request.Cookies["ShipFromAddress"].Value);
Concrete class
public class ShipFromAddress
{
public string Weight
{
get;
set;
}
public string addressLine1
{
get;
set;
}
public string addressLine2
{
get;
set;
}
public string city
{
get;
set;
}
public string postcode
{
get;
set;
}
public string countrycode
{
get;
set;
}
public string StateCode
{
get;
set;
}
}
I do not want to create or use concrete class rather I want to do that deserialization on the fly with the help of dynamic object or anonymous class concept. Please guide me with sample code.
i got two solution.....which looks good
1) when need to pass multiple data serialize to anonymous the example would be
var query = from employee in employees select new { Name = employee.Name, Id = employee.Id };
LogEmployees(query);
public void LogEmployees (IEnumerable<dynamic> list)
{
foreach (dynamic item in list)
{
string name = item.Name;
int id = item.Id;
}
}
method argument type must be IEnumerable<dynamic> because LogEmployees() function expecting multiple data
2) when passing single data the code look like
public class Program
{
private static void Thing(dynamic other)
{
Console.WriteLine(other.TheThing);
}
private static void Main()
{
var things = new { TheThing = "Worked!" };
Thing(things);
}
}
With JavaScriptSerializer you can use the DeserializeObject method from serializer which will return just an object:
JavaScriptSerializer jss = new JavaScriptSerializer();
object obj= jss.DeserializeObject(Request.Cookies["ShipFromAddress"].Value);
Internally it will be represented as a Dictionary<string, object>, so you can cast it to it and use like this:
var values = (Dictionary<string, object>)jss.DeserializeObject(Request.Cookies["ShipFromAddress"].Value);
var addressLine1 = values["addressLine1"].ToString();
Or you can cast it to dynamic:
dynamic values = jss.DeserializeObject(Request.Cookies["ShipFromAddress"].Value);
var addressLine1 = values["addressLine1"].ToString();
Alternatively, You can use Json.NET library and it's JsonConvert class (benchmarks show that it performs faster than JavaScriptSerializer). The code will look like this:
dynamic values = JsonConvert.DeserializeObject(Request.Cookies["ShipFromAddress"].Value);
var addressLine1 = values.addressLine1;
I use Newtonsoft.Json
string source = Request.Cookies["ShipFromAddress"].Value as string;
var address = JsonConvert.DeserializeObject<ShipFromAddress>(source);

Parsing unique collection using LINQ to JSON

I am trying to parse a JSON feed using LINQ and can't quite wrap a list of objects/values into a reasonable class.
My JSON looks like:
{
"Project":[
{
"ID":"XY1212",
"Name":"Some Name",
"Description":"U.S. No 2 Diesel Retail Prices",
"Manager":"Nora Sims",
"Dept":"HR",
"Updated":"2014-07-22",
"Statistics":[
[
"20140722",
32.22
],
[
"20140721",
55
],
[
"20140720",
343
],
[
"20140519",
43
],
[
"20140421",
3.971
],
[
"20140211",
40.2
],
[
"20140210",
17
],
[
"20140209",
16
]
]
}
]
}
From the above JSON, I have the following class structure:
public class Project
{
public string ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Manager { get; set; }
public string Dept { get; set; }
public string Updated { get; set; }
public List<List<object>> Statistics { get; set; }
}
public class RootObject
{
public List<Project> Project { get; set; }
}
public class Statistic
{
public Datetime ProjectDate { get; set; }
public Decimal Sale { get; set; }
}
I am trying to parse the feed and just want the "Statistics" data, but not sure how to get all of the values into the collection of "Statistics":
HttpClient() http = new HttpClient();
var json = await http.GetStringAsync(uri);
JObject jo = JObject.Parse(json);
var jList = from values in jo["Project"].Children()["Statistics"]
select values;
When I inspect jList via the following loop:
foreach (var stat in jList)
{
Console.WriteLine(stat);
}
I can "see" all of the values, but it only loops once, i.e. jList is only one big [0] with a "value" of all of the [x, y], [x1, y1], ..., i.e. looks like an array of one dimension with many 2D arrays inside it.
I want to loop through all of the "arrays", I believe that's what they are, within the [0] I see in Visual Studio while debugging.
Any advice appreciated.
You can solve this easily by making a custom JsonConverter for your Statistic class. It will deal with the unconventional JSON and allow you to define your Project class the way you'd really like to have it.
Here is the code for the converter:
class StatisticConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(Statistic));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JArray array = JArray.Load(reader);
return new Statistic
{
ProjectDate = DateTime.ParseExact(array[0].ToString(), "yyyyMMdd",
System.Globalization.CultureInfo.InvariantCulture),
Sale = array[1].ToObject<decimal>()
};
}
public override bool CanWrite
{
get { return false; }
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
To use the converter, we just need to make a couple of minor changes to your classes. First, change the Statistics property to be a List<Statistic> instead of a List<List<object>>. (Don't worry that it doesn't match the JSON-- that's what the converter is for.)
public class Project
{
public string ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Manager { get; set; }
public string Dept { get; set; }
public string Updated { get; set; }
public List<Statistic> Statistics { get; set; }
}
Next decorate your Statistic class with a [JsonConverter] attribute to tie it to the custom converter:
[JsonConverter(typeof(StatisticConverter))]
public class Statistic
{
public DateTime ProjectDate { get; set; }
public Decimal Sale { get; set; }
}
That's it! Now you can deserialize as normal, and you'll get a list of statistics the way you want.
RootObject root = JsonConvert.DeserializeObject<RootObject>(json);
Working demo here.
The problem isn't your code so much as it is the JSON string that is coming back from the HttpClient.
Because it has parts that don't have a key, it is hard to sort through, also each child of statistic is a child of that child (If my eyes don't deceive me).
However, using the code below, I am able to read the Statistics values singularly
JObject jo = JObject.Parse(json);
var jList = from values in jo["Project"]
select values;
foreach (var j in jList)
{
var l = j["Statistics"].Children();
foreach (var m in l.Children())
{
string a = m.ToString();
}
}
On the first loop, m has the Date, On the second loop it has the sale. because there is no key for these, I don't know any other way to reference them.
A bit less code but similar result
JObject jo = JObject.Parse(json);
for (int i = 0; i < jo.Count; i++)
{
var jList = from values in jo["Project"][i]["Statistics"]
select values;
foreach (var stat in jList)
{
//here stat looks like {["20140722", 32.22]}
}
}

JavaScriptDeseializer : Can not serialize array

My application is asp.net. I have to send some values back to server. For this I create a object serialize it and send it to server. At server I try to de-serialize it
Following is my code
[Serializable]
public class PassData
{
public PassData()
{
}
public List<testWh> SelectedId { get; set; }
public string SelectedControlClientId { get; set; }
public string GroupTypeId { get; set; }
public string SectionTypeId { get; set; }
}
[Serializable]
public class testWh
{
public testWh()
{
}
public string Id { get; set; }
}
JavaScriptSerializer serializer = new JavaScriptSerializer();
//this can not serialize the SelectedId and the count remains 0
PassData data = serializer.Deserialize<PassData>(jsonString);
//this serialize in an anonymous object with key value pair
var data2 = serializer.DeserializeObject(textHiddenArguments.Text);
Following is my Json Serialized String
{
"SelectedId":{"0":"ABCD","1":"JKLM"},
"SelectedControlClientId":"YTUTOOO",
"GroupTypeId":3,
"SectionTypeId":"1"
}
quotes escaped string
"{\"SelectedId\":{\"0\":\"ABCD\",\"1\":\"JKLM\"},\"SelectedControlClientId\":\"YTUTOOO\",\"GroupTypeId\":3,\"SectionTypeId\":\"1\"}"
My Problem is Selected Id is array of testWH object. But when I try to desrialize it, the SelectedId property of PassData which is list does not get serialized and count remains zero.
I tried using array instead of List, which gave an exception "no parameter less constructor..."
Could any one explain the what I am doing wrong here ?
The key problem here is that the JSON doesn't match the objects you have constructed. You can see this by writing the data you want and serializing:
var obj = new PassData
{
SelectedId = new List<testWh>
{
new testWh { Id = "ABCD"},
new testWh { Id = "JKLM"}
},
GroupTypeId = "3",
SectionTypeId = "1",
SelectedControlClientId = "YTUTOOO"
};
string jsonString = serializer.Serialize(obj);
which gives JSON like:
{"SelectedId":[{"Id":"ABCD"},{"Id":"JKLM"}],
"SelectedControlClientId":"YTUTOOO","GroupTypeId":"3","SectionTypeId":"1"}
So now you need to decide which you want to change; the JSON or the classes. The following alternative class works fine with your original JSON, for example:
public class PassData
{
public Dictionary<string,string> SelectedId { get; set; }
public string SelectedControlClientId { get; set; }
public string GroupTypeId { get; set; }
public string SectionTypeId { get; set; }
}

Categories