Json.NET – 直接从流反序列化为动态?

在Json.NET文档中的性能提示的帮助下,我整理了一个从远程资源下载/反序列化JSON的方法:

public async Task GetJsonAsync(string url) { using (var stream = await new HttpClient().GetStreamAsync(url)) { using (var sr = new StreamReader(stream)) { using (var jr = new JsonTextReader(sr)) { return new JsonSerializer().Deserialize(jr); } } } } 

我想要一个返回dynamic的非generics版本。 用GetJsonAsync(url)调用上面的方法是有效的,直到你尝试访问结果的动态属性,此时我得到:

 'Newtonsoft.Json.Linq.JObject' does not contain a definition for '[MyProperty]' 

我已经看到如何从字符串反序列化为动态 ,但是还没有看到直接从流中执行它的工作示例,这将是更好的,因为它更有内存效率。 这可能吗?

事实certificate,这与Json.NET几乎没有关系,更多的是与我对动力学的理解(我很少使用)。 感谢@Peter Richie,我发现如果我将MyProperty明确地转换为字符串, GetJsonAsync会起作用。 但我宁愿不必那样做。 使用我的原始方法和实际工作端点 ,这里有3个场景; 只有最后一个有效:

 var url = "http://echo.jsontest.com/MyProperty/MyValue"; // great testing site! var x1 = await GetJsonAsync(url); Assert.AreEqual("MyValue", x1.MyProperty); // fail! dynamic x2 = await GetJsonAsync(url); Assert.AreEqual("MyValue", x2.MyProperty); // fail! dynamic x3 = await GetJsonAsync(url); Assert.AreEqual("MyValue", x3.MyProperty); // pass! 

有了这些知识,我原始方法的非generics重载看起来像这样:

 public async Task GetJsonAsync(string url) { dynamic d = await GetJsonAsync(url); return d; } 

用户可以这样做:

 var x = await GetJsonAsync(url); Assert.AreEqual("MyValue", x.MyProperty); // pass! 

听起来有些信息是你没有提供的。 以下工作对我来说很好:

  private T ReadJson(Stream stream) { using (var reader = new StreamReader(stream)) { using (var jr = new JsonTextReader(reader)) { dynamic d = new JsonSerializer().Deserialize(jr); return d; } } } //... var d = ReadJson(new MemoryStream(Encoding.UTF8.GetBytes("{'MyProperty' : 'MyValue'}"))); Debug.WriteLine((String)d.MyProperty);