繁体   English   中英

将Json反序列化为ObservableCollection

[英]Deserializing Json into ObservableCollection

我正在尝试使用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返回的FooEmployees计数为0。

谁能指导我为什么它不起作用?

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

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

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

  1. 更改JSON以消除多余的图层。
  2. 定义一个包装器类(例如EmployeeHolder )以表示JSON中的额外层,并使FooEmployees成为这些FooEmployees的集合。
  3. 实现JSON转换器,以在反序列化过程中抽象出多余的层。 请参阅是否可以在不为每个项目使用包装器类的情况下反序列化我的JSON? 有关此方法的更多详细信息。

我通常不混合使用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};

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

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

尝试删除abstract关键字。

我想将所有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);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM