2017-03-21 75 views
0

嗯,我是編程新手,我有一個問題。反序列化Json C#錯誤

這是我的課VALORES

public class Valores 
    { 
     [JsonProperty("nome")] 
     public string Nome { get; set; } 
     [JsonProperty("valor")] 
     public double Valor { get; set; } 
     [JsonProperty("ultima_consulta")] 
     public int UltimaConsulta { get; set; } 
     [JsonProperty("fonte")] 
     public string Fonte { get; set; } 
    } 

這是我的方法,我得和反序列化的json

public static async Task<Valores> GetAsync() 
    { 
     Valores valores = null; 

      using (var client = new HttpClient()) 
      { 
       var json = await client.GetStringAsync("http://api.promasters.net.br/cotacao/v1/valores"); 
       valores = JsonConvert.DeserializeObject<Valores>(json); 
      } 

     return valores; 
    } 

這是JSON的道: 「http://api.promasters.net.br/cotacao/v1/valores」 的回報。

{ 
    "status": true, 
    "valores": { 
    "USD": { 
     "nome": "Dólar", 
     "valor": 3.0717, 
     "ultima_consulta": 1490040302, 
     "fonte": "UOL Economia - http://economia.uol.com.br/" 
    }, 
    "EUR": { 
     "nome": "Euro", 
     "valor": 3.3002, 
     "ultima_consulta": 1490040302, 
     "fonte": "UOL Economia - http://economia.uol.com.br/" 
    }, 
    "ARS": { 
     "nome": "Peso Argentino", 
     "valor": 0.1965, 
     "ultima_consulta": 1490040302, 
     "fonte": "UOL Economia - http://economia.uol.com.br/" 
    }, 
    "GBP": { 
     "nome": "Libra Esterlina", 
     "valor": 3.7966, 
     "ultima_consulta": 1490040302, 
     "fonte": "UOL Economia - http://economia.uol.com.br/" 
    }, 
    "BTC": { 
     "nome": "Bitcoin", 
     "valor": 3472, 
     "ultima_consulta": 1490067603, 
     "fonte": "Mercado Bitcoin - http://www.mercadobitcoin.com.br/" 
    } 
    } 
} 

我不知道我做錯了什麼,因爲這

VAR JSON =等待client.GetStringAsync( 「http://api.promasters.net.br/cotacao/v1/valores」);

這是接收字符串Json,但沒有收到任何東西,它就像一個空字符串。

回答

1

我試驗了一下,它出現在網站要求user agent請求字符串以設定的東西要返回JSON。而且,通過某種方式,我的意思是字符串"something"似乎正常工作,字符串"Wget/1.11.4"也一樣。您應該檢查documentation(葡萄牙語),以確保沒有任何編程訪問本網站的限制,並遵守那些訪問限制(如果有)。

此外,您的數據模型不會反映您的JSON。你需要一個更高層次的根對象如下:

public class RootObject 
{ 
    public RootObject() { this.valores = new Dictionary<string, Valores>(); } 

    public bool status { get; set; } 
    public Dictionary<string, Valores> valores { get; set; } 
} 

這裏是一個sample fiddle,成功地下載,並通過設置用戶代理從網站反序列化JSON。它採用WebClient因爲這似乎是可以用https://dotnetfiddle.net/

public static async Task<RootObject> GetAsync() 
{ 
    using (var client = new WebClient()) 
    { 
     client.Headers["User-Agent"] = "something"; 
     var json = await client.DownloadStringTaskAsync(@"http://api.promasters.net.br/cotacao/v1/valores"); 
     var root = JsonConvert.DeserializeObject<RootObject>(json); 
     return root; 
    } 
} 

併爲HttpClient我想應該是(未經測試):

public static async Task<RootObject> GetAsync() 
{ 
    var client = new HttpClient(); 

    client.DefaultRequestHeaders.Add("User-Agent", "something"); 
    var json = await client.GetStringAsync("http://api.promasters.net.br/cotacao/v1/valores"); 
    return JsonConvert.DeserializeObject<RootObject>(json); 
} 

參見this post對於是否處置的討論HttpClient

0

這裏的問題是反序列化的json沒有正確映射到一個對象。嘗試在你的模型(Valores)上創建一個包裝類,然後嘗試映射。

public class Valores 
{ 
    [JsonProperty("nome")] 
    public string Nome { get; set; } 
    [JsonProperty("valor")] 
    public double Valor { get; set; } 
    [JsonProperty("ultima_consulta")] 
    public int UltimaConsulta { get; set; } 
    [JsonProperty("fonte")] 
    public string Fonte { get; set; } 
} 

public class ValoresList 
{ 
    public boolean status { get; set; } 
    public Valores USD { get; set; } 
    public Valores EUR { get; set; } 
    public Valores ARS { get; set; } 
    public Valores GBP { get; set; } 
    public Valores BTC { get; set; } 
} 

然後將包裝類映射到反序列化的json。

public static async Task<ValoresList> GetAsync() 
{ 
    ValoresList valores = null; 

    using (var client = new HttpClient()) 
    { 
     var json = await client.GetStringAsync("http://api.promasters.net.br/cotacao/v1/valores"); 
     valores = JsonConvert.DeserializeObject<ValoresList>(json); 
    } 

    return valores; 
} 
0

問題是json返回的字典中包含Valores集合,您試圖將響應映射到單個Valore對象。

你的容器想看起來像這樣。字典的關鍵是貨幣的字符串表示。

class Container 
{ 
    public bool Status { get; set; } 
    public Dictionary<string, ValorInfo> Valores { get; set; } 
} 

您的勇氣等級很好,我重命名它以防止類別名稱與Valor屬性發生衝突。

class ValorInfo 
{ 
    [JsonProperty("nome")] 
    public string Nome { get; set; } 
    [JsonProperty("valor")] 
    public double Valor { get; set; } 
    [JsonProperty("ultima_consulta")] 
    public int UltimaConsulta { get; set; } 
    [JsonProperty("fonte")] 
    public string Fonte { get; set; } 
} 

最後,這是你如何使用它,支持@dbc來發現用戶代理需求,這讓我難住!

async void Main() 
{ 
    using (var client = new HttpClient()) 
    { 
     client.DefaultRequestHeaders.Add("Accept", "application/json"); 
     client.DefaultRequestHeaders.Add("User-Agent", "linqpad"); 

     var response = await client.GetAsync("http://api.promasters.net.br/cotacao/v1/valores"); 
     response.EnsureSuccessStatusCode(); 

     var container = await response.Content.ReadAsAsync<Container>(); 

     // do stuff with container... 
    } 
}