繁体   English   中英

将JSON数组反序列化为ObservableCollection

[英]Deserializing a JSON array to a ObservableCollection

我正在使用RestSharp与远程服务器通信。 我收到一个JSON序列化字符串,我可以反序列化为ac#对象。 我也能够将json数组反序列化为List。 但是,我希望这些对象在WPF绑定中使用,所以我需要将它们放在ObservableCollection中以方便使用。 但是,如果我尝试将属性从List更改为ObservableCollection(或IList,或ICollection或Collection),则会在反序列化时出现异常。

Unable to cast object of type 'RestSharp.JsonArray' to type 'System.Collections.Generic.IDictionary`2[System.String,System.Object]

底层代码真的不是特别的,但无论如何它在这里:

private ObservableCollection<StationDto> stations;

[JsonProperty(PropertyName = "stations")]
public ObservableCollection<StationDto> Stations
{
    get { return this.stations; }
    set
    {
        this.stations = value;
        RaisePropertyChanged(() => Stations);
    }
}

我知道接口不起作用,因为Json.net需要一个具体的类来序列化。

我已经做了相当多的谷歌搜索,但我还没有看到解决方案。 是否有一种常用于json / rest服务的手工代理的模式?

查看RestSharp源代码 ,看起来它使用自己的内部JSON反序列化器(称为SimpleJson),而不是使用Json.Net。 反序列化RestSharp文档确认反序列化器仅支持List<T>Dictionary<T1,T2>集合类型。 另一方面, Json.Net更强大,可以处理反序列化为ObservableCollections。 我在这篇文章的最后用代码尝试了它并没有看到任何问题。 考虑到这一点,我建议将Json.Net添加到您的解决方案中,并使用它来反序列化REST API调用的结果,而不是依赖于RestSharp的内部反序列化器。 有几种方法可以做到这一点:

  1. 您可以调用Execute()而不是在RestClient上调用Execute<T>() Execute()返回一个IRestResponse ,它具有一个Content属性,该属性将包含从请求返回的原始JSON字符串。 您可以获取此字符串并将其传递给Json.Net的JsonConvert.DeserializeObject<T>()方法。

  2. 创建一个实现RestSharp的IDeserializer接口的类。 让这个类简单地交给Json.Net来完成反序列化JSON的实际工作。 然后,您可以通过在RestClient类上调用AddHandler()来告诉RestSharp使用此自定义反序列化器而不是它自己的。 根据文档,您以这种方式添加的处理程序将替换相同内容类型的现有处理程序。 然后,您可以继续以与RestClient相同的方式使用RestClient ,但它现在应该与ObservableCollections

这是我用来测试Json.Net将反序列化为ObservableCollection

class Program
{
    static void Main(string[] args)
    {
        string json = @"{""stations"":[{""Name"":""WXRT""},{""Name"":""WGN""}]}";

        Foo foo = JsonConvert.DeserializeObject<Foo>(json);

        foreach (StationDto dto in foo.Stations)
        {
            Console.WriteLine(dto.Name);
        }
    }
}

class StationDto
{
    public string Name { get; set; }
}

class Foo
{
    private ObservableCollection<StationDto> stations;

    [JsonProperty(PropertyName = "stations")]
    public ObservableCollection<StationDto> Stations
    {
        get { return this.stations; }
        set 
        { 
            this.stations = value;
            RaisePropertyChanged(() => Stations);
        }
    }

    private void RaisePropertyChanged(Func<ObservableCollection<StationDto>> coll)
    {
    }
}

暂无
暂无

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

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