Reputation: 627
I'm trying to deserialize this Json using Json.Net lib.:-
{
"Employees": [
{
"Employee": {
"Name": "AAA",
"Info": [
{
"Signature": "aaa"
},
{
"Group": "AaA"
},
{
"E-mail": "aAa"
},
{
"Tfn home": "1234"
},
{
"Tfn mobile": "1324"
},
{
"Tfn work": "1234"
},
{
"Tfn pager": "1234"
}
]
}
},
{
"Employee": {
"Name": "BBB",
"Info": [
{
"Signature": "bbb"
},
{
"Group": "BbB"
},
{
"E-mail": "bBb"
},
{
"Tfn home": "1234"
},
{
"Tfn mobile": "1234"
},
{
"Tfn work": "1234"
},
{
"Tfn pager": "1234"
}
]
}
}
]
}
Into the following:-
public class Foo
{
private ObservableCollection<Employee> _fooEmployees = new ObservableCollection<Employee>();
public ObservableCollection<Employee> FooEmployees
{
get { return _fooEmployees; }
set { _fooEmployees = value; }
}
}
[JsonObject]
public class Employee
{
[JsonProperty(PropertyName = "Name")]
public string Name { get; set; }
[JsonProperty(PropertyName = "Info")]
private ObservableCollection<Infomation> _infoList = new ObservableCollection<Infomation>();
public ObservableCollection<Infomation> InfoList
{
get { return _infoList; }
set
{
_infoList = value;
}
}
}
[JsonDictionary]
public abstract class Infomation
{
[JsonProperty(PropertyName = "Signature")]
public string Signature { get; set; }
[JsonProperty(PropertyName = "Group")]
public string Group { get; set; }
[JsonProperty(PropertyName = "E-mail")]
public string Email { get; set; }
[JsonProperty(PropertyName = "Tfn home")]
public string TfnHome { get; set; }
[JsonProperty(PropertyName = "Tfn mobile")]
public string TfnMobile { get; set; }
[JsonProperty(PropertyName = "Tfn work")]
public string TfnWork { get; set; }
[JsonProperty(PropertyName = "Tfn pager")]
public string TfnPager { get; set; }
}
Using the following line of code:-
var kol = JsonConvert.DeserializeObject<Foo>(json);
The problem is that Kol return FooEmployees with 0 Count.
Anyone who can direct me to why it is not working?
Upvotes: 4
Views: 11685
Reputation: 2380
I wanted to deserialize all ICollection
s as ObservableCollection
s. I could solve it with a very simple custom contract resolver:
public class JsonObservableCollectionConverter : DefaultContractResolver
{
public JsonObservableCollectionConverter(bool shareCache) : base(shareCache)
{
}
public override JsonContract ResolveContract(Type type)
{
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ICollection<>))
{
return ResolveContract(typeof(ObservableCollection<>).MakeGenericType(type.GetGenericArguments()));
}
return base.ResolveContract(type);
}
}
var settings = new JsonSerializerSettings
{
ContractResolver = new JsonObservableCollectionConverter(true),
};
var result = JsonConvert.DeserializeObject<IEnumerable<TResult>>(json, settings);
Upvotes: 1
Reputation: 129717
You're getting an empty collection because your classes don't match your JSON. I see at least two issues:
First, the outer JSON object has a property called Employees
but the Foo
class you are deserializing into has a property called FooEmployees
. Since the names don't match, your FooEmployees
collection will remain empty. Try adding a [JsonProperty("Employees")]
attribute to the FooEmployees
property like you did elsewhere in your code.
Second, the Employees
collection in the JSON does not actually contain a collection of Employee
objects as you have defined them in your classes. Instead, it contains a collection of objects that each have single property called Employee
which contains an Employee
instance. To fix this, you can do one of the following:
EmployeeHolder
) to represent the extra layer in the JSON, and make FooEmployees
a collection of those.Upvotes: 4
Reputation: 149538
You are holding an ObservableCollection, but Information is an abstract class. How do you expect it to create an instance of Information?
Try removing the abstract keyword.
Upvotes: 1
Reputation: 35870
I generally don't mix my DTOs (an example would be what JSON deserializes into: Foo) and view model classes (classes that contain ObservableCollections or implement INotifyPropertyChanged, etc. and bind to visual controls)
I would deserialize into a plain old class (one that doesn't use ObservableCollection) and then populate a view model class from there. For example:
public class Foo
{
private List<Employee> _fooEmployees = new List<Employee>();
public List<Employee> FooEmployees
{
get { return _fooEmployees; }
set { _fooEmployees = value; }
}
//...
}
public class ViewModel
{
public ObservableCollection<Employee> FooEmployees {get;set;}
//....
}
//...
var dto = JsonConvert.DeserializeObject<Foo>(json);
var vm = new ViewModel{FooEmployees = dto.Employees};
(or maybe do a "copy constructor")...
Upvotes: 1