Json.NET – désérialiser directement d’un stream à une dynamic?

Avec un peu d’aide des conseils de performance contenus dans la documentation Json.NET, j’ai élaboré une méthode de téléchargement / désérialisation de JSON à partir d’une ressource distante:

public async Task GetJsonAsync(ssortingng 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); } } } } 

J’aimerais avoir une version non générique qui renvoie une dynamic . L’appel de la méthode ci-dessus avec GetJsonAsync(url) fonctionne jusqu’à ce que vous essayiez d’accéder à une propriété dynamic sur le résultat. À ce stade, je reçois:

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

J’ai vu comment désérialiser une dynamic à partir d’une chaîne, mais je n’ai pas vu d’exemple concret de le faire directement à partir d’un stream, ce qui serait préférable car il utilise plus efficacement la mémoire. Est-ce possible?

Il s’avère que cela a peu à voir avec Json.NET et plus avec ma compréhension de la dynamic (que j’utilise rarement). Grâce à @Peter Richie, j’ai découvert que GetJsonAsync fonctionnait si je convertissais explicitement MyProperty en chaîne. Mais je préférerais ne pas avoir à faire ça. En utilisant ma méthode originale et un noeud final réel , voici 3 scénarios; seul le dernier fonctionne:

 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! 

Fort de cette connaissance, la surcharge non générique de ma méthode d’origine ressemble à ceci:

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

Et les utilisateurs peuvent le faire:

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

On dirait qu’il y a des informations que vous n’avez pas fournies. Ce qui suit fonctionne bien pour moi:

  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((Ssortingng)d.MyProperty);