Urb*_*Esc 3 c# .net-4.0 json.net restsharp
我正在使用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]
Run Code Online (Sandbox Code Playgroud)
底层代码真的不是特别的,但无论如何它在这里:
private ObservableCollection<StationDto> stations;
[JsonProperty(PropertyName = "stations")]
public ObservableCollection<StationDto> Stations
{
get { return this.stations; }
set
{
this.stations = value;
RaisePropertyChanged(() => Stations);
}
}
Run Code Online (Sandbox Code Playgroud)
我知道接口不起作用,因为Json.net需要一个具体的类来序列化.
我已经做了相当多的谷歌搜索,但我还没有看到解决方案.是否有一种常用于json/rest服务的手工代理的模式?
查看RestSharp的源代码,看起来它使用自己的内部JSON反序列化器(称为SimpleJson),而不是使用Json.Net.反序列化的RestSharp文档确认反序列化器仅支持List<T>和Dictionary<T1,T2>集合类型. 另一方面,Json.Net更强大,可以处理反序列化为ObservableCollections.我在这篇文章的最后用代码尝试了它并没有看到任何问题.考虑到这一点,我建议将Json.Net添加到您的解决方案中,并使用它来反序列化REST API调用的结果,而不是依赖于RestSharp的内部反序列化器.有几种方法可以做到这一点:
而不是调用的Execute<T>()对RestClient,你可以打电话Execute()来代替. Execute()返回一个IRestResponse具有Content属性的属性,该属性将包含从请求返回的原始JSON字符串.您可以使用此字符串并将其传递给Json.Net的JsonConvert.DeserializeObject<T>()方法.
创建一个实现RestSharp IDeserializer接口的类.让这个类简单地交给Json.Net来完成反序列化JSON的实际工作.然后,您可以告诉RestSharp通过调用使用这个定制的解串器,而不是它自己AddHandler()的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)
{
}
}
Run Code Online (Sandbox Code Playgroud)