Json.NET-直接从流反序列化为动态? [英] Json.NET - deserialize directly from a stream to a dynamic?
问题描述
在性能提示在Json.NET文档中,我提出了一种用于从远程资源下载/反序列化JSON的方法:
With a little help from the performance tips in the Json.NET docs, I put together a method for downloading/deserializing JSON from a remote resource:
public async Task<T> GetJsonAsync<T>(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<T>(jr);
}
}
}
}
我想有一个返回dynamic
的非通用版本.用GetJsonAsync<dynamic>(url)
调用上述方法有效,直到尝试访问结果的动态属性为止,此时我得到:
I'd like to have a non-generic version that returns a dynamic
. Calling the above method with GetJsonAsync<dynamic>(url)
works, until you try to access a dynamic property on the result, at which point I get:
'Newtonsoft.Json.Linq.JObject' does not contain a definition for '[MyProperty]'
我已经看到如何反序列化为动态从字符串开始,但是还没有看到直接从流中直接执行的工作示例,这将是更可取的,因为它可以提高内存效率.这可能吗?
I have seen how to deserialize to a dynamic from a string, but have not seen a working example of doing it directly from a stream, which would be preferable as it is more memory efficient. Is this possible?
推荐答案
事实证明,这与Json.NET无关,而与我对动力学的理解(我很少使用)有关.感谢@Peter Richie,我发现如果将MyProperty显式转换为字符串,GetJsonAsync<dynamic>
确实可以工作.但是我宁愿不必那样做.使用我的原始方法和真实的工作端点,这里有3种情况:只有最后一个有效:
It turns out this had little to do with Json.NET and more to do with my understanding of dynamics (which I rarely use). Thanks to @Peter Richie, I found that GetJsonAsync<dynamic>
does work if I explicitly cast MyProperty to a string. But I'd rather not have to do that. Using my original method and a real working endpoint, here are 3 scenarios; only the last one works:
var url = "http://echo.jsontest.com/MyProperty/MyValue"; // great testing site!
var x1 = await GetJsonAsync<dynamic>(url);
Assert.AreEqual("MyValue", x1.MyProperty); // fail!
dynamic x2 = await GetJsonAsync<dynamic>(url);
Assert.AreEqual("MyValue", x2.MyProperty); // fail!
dynamic x3 = await GetJsonAsync<ExpandoObject>(url);
Assert.AreEqual("MyValue", x3.MyProperty); // pass!
有了这些知识,我原始方法的非泛型重载看起来像这样:
Armed with that knowledge, the non-generic overload of my original method looks like this:
public async Task<dynamic> GetJsonAsync(string url) {
dynamic d = await GetJsonAsync<ExpandoObject>(url);
return d;
}
用户可以执行以下操作:
And users can do this:
var x = await GetJsonAsync(url);
Assert.AreEqual("MyValue", x.MyProperty); // pass!
这篇关于Json.NET-直接从流反序列化为动态?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!