将Json反序列化为ObservableCollection

4

我试图使用Json.Net库对这个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"
                    }
                ]
            }
        }
    ]
}

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

使用以下代码行:-
var kol = JsonConvert.DeserializeObject<Foo>(json);

问题在于Kol返回的FooEmployees数量为0。
请问有人能指导我为什么它不起作用吗?

你还应该包含你的Information类的代码。Information是如何进行序列化/反序列化的? - Ben Smith
@Fresh 对不起,我想我错过了这部分,请再看一下代码,我已经添加了缺少的信息。 - DreamNet
4个回答

4
您得到了一个空集合,因为您的类与JSON不匹配。我至少看到两个问题:
首先,外部JSON对象有一个名为Employees的属性,但您正在反序列化为的Foo类具有名为FooEmployees的属性。由于名称不匹配,您的FooEmployees集合将保持为空。尝试像在代码其他地方一样,在FooEmployees属性中添加一个[JsonProperty("Employees")]属性。
其次,JSON中的Employees集合实际上并不包含与您在类中定义的Employee对象集合相同的对象。相反,它包含一个对象集合,每个对象都有一个名为Employee的属性,其中包含一个Employee实例。要解决此问题,您可以执行以下操作之一:
1. 更改JSON以消除额外的层。 2. 定义一个包装器类(例如EmployeeHolder)来表示JSON中的额外层,并使FooEmployees成为这些类的集合。 3. 实现JSON转换器以在反序列化期间抽象掉额外的层。有关此方法的更多详细信息,请参见是否有一种方法可以在不使用每个项目的包装器类的情况下反序列化我的JSON?

谢谢,你说得完全正确。在看到你的回答之前,我通过试错和阅读JSON.Net来学习它。我的类与JSON不匹配,现在我已经改变了这一点,现在一切都像魔法一样运作。我甚至发现了我JSON数据中不需要的层,并进行了修改 ;)。 - DreamNet

1
我希望将所有的ICollection反序列化为ObservableCollection。我可以通过一个非常简单的自定义合同解析器来解决这个问题:
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);

1
您正在使用一个ObservableCollection,但Information是一个抽象类。您怎么能期望它创建一个Information的实例呢?
尝试删除abstract关键字。

这是一个错误,我已经移除了。不管怎样,感谢你指出了这个问题。 - DreamNet

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

(或者做一个“复制构造函数”)...

我已经测试了一个普通类,但是列表中仍然得到了0计数。有任何想法为什么会这样吗? - DreamNet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接