将Json反序列化为ObservableCollection

时间:2014-04-07 22:39:03

标签: c# json.net

我试图使用Json.Net lib反序列化这个Json。: -

{
    "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"
                    }
                ]
            }
        }
    ]
}

进入以下内容: -

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; }
}

使用以下代码行: -

var kol = JsonConvert.DeserializeObject<Foo>(json);

问题是Kol以0 Count返回FooEmployees。

任何可以指导我为什么不工作的人?

4 个答案:

答案 0 :(得分:2)

您收到一个空集合,因为您的类与您的JSON不匹配。我至少看到两个问题:

首先,外部JSON对象具有名为Employees的属性,但您要反序列化的Foo类具有名为FooEmployees的属性。由于名称不匹配,您的FooEmployees集合将保持为空。尝试将[JsonProperty("Employees")]属性添加到FooEmployees属性,就像在代码中的其他位置一样。

其次,JSON中的Employees集合实际上并不包含Employee个对象的集合,因为您已在类中定义它们。相反,它包含一组对象,每个对象都有一个名为Employee的单个属性,其中包含Employee个实例。要解决此问题,您可以执行以下操作之一:

  1. 更改您的JSON以消除额外的图层。
  2. 定义一个包装类(例如EmployeeHolder)来表示JSON中的额外层,并使FooEmployees成为这些层的集合。
  3. 实现JSON转换器以在反序列化期间抽象出额外的层。有关此方法的详细信息,请参阅Is there a way to deserialize my JSON without using a wrapper class for each item?

答案 1 :(得分:1)

我通常不会混合我的DTO(一个例子是JSON反序列化为Foo)和查看模型类(包含ObservableCollections的类或实现INotifyPropertyChanged等,并绑定到可视控件)

会反序列化为一个普通的旧类(一个不使用ObservableCollection的类),然后从那里填充一个视图模型类。例如:

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};

(或者做一个&#34;复制构造函数&#34;)...

答案 2 :(得分:1)

您持有ObservableCollection,但Information是一个抽象类。 您如何期望它创建信息实例?

尝试删除抽象关键字。

答案 3 :(得分:1)

我想将所有ICollection反序列化为ObservableCollection s。我可以用一个非常简单的自定义合约解析器来解决它:

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);