2016-07-06 71 views
1

我的方法是這樣的:UWP和JSON解析

public static async void DoSomething() 
{ 
    try 
    { 
     var client = new HttpClient(); 
     var url = "http://10.0.0.68/SET Initialization"; 
     var url2 = "http://10.0.0.68/GET Status"; 
     var response = await client.GetAsync(url); 
     Debug.WriteLine(response); 
     response = await client.GetAsync(url2); 
     Debug.WriteLine(response); 
     var result =await response.Content.ReadAsStringAsync(); 
     var jsonString = result.Substring(4); 
     var serializer = new DataContractJsonSerializer(typeof(MediaStatus)); 
     var ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)); 
     var data = (MediaStatus)serializer.ReadObject(ms); 
     Debug.Write(data.ProgNo); 
    } 
    catch (Exception exception) 
    { 
     Debug.WriteLine(exception.Message, exception.Source); 
    } 
} 

MediaStatus.cs

[DataContract] 
public class MediaStatus 
{ 
    [DataMember(Name = "progNo")] 
    public int ProgNo { get; set; } 
    [DataMember(Name = "index")] 
    public int Index { get; set; } 
    [DataMember(Name = "type")] 
    public string Type { get; set; } 
    [DataMember(Name = "group")] 
    public int Group { get; set; } 
    [DataMember(Name = "msg")] 
    public string Msg { get; set; } 
    [DataMember(Name = "secondGroup")] 
    public int SecondGroup { get; set; } 
    [DataMember(Name = "playFlag")] 
    public int PlayFlag { get; set; } 
} 

我簡單地調用它:

common.DoSomething(); 

我的問題是,有時,代碼運行良好,並會給我結果,但有時我有一個錯誤:

Exception thrown: 'System.Runtime.Serialization.SerializationException' in System.Private.DataContractSerialization.dll System.Private.DataContractSerialization:Expecting element 'root' from namespace ''.. Encountered 'None' with name '', namespace ''.

我要叫兩次await client.GetAsync網址不同

  1. 說我想服務器和他說話
  2. 以獲取狀態信息
+1

你在異步方法,爲什麼您使用。結果,而不是等待?無論如何,發佈它引發的Json。你可能沒有得到任何返回的Json,它正在拋出。 – Dispersia

+0

您好,感謝您的回覆,我將其更改爲: var result = await response.Content.ReadAsStringAsync(); 但沒有幫助 – petrtim

+0

這可能是畸形的JSON。你可以發佈JSON本身嗎? –

回答

0

這是這是一個經典的問題,你在調用fire-and-forget,因爲你的DoSomething方法被定義爲async void。應該標記爲void方法的唯一入口點是事件處理程序等。這種方法應該改爲Task返回這樣的:

public static async Task DoSomethingAsync() 
{ 
    try 
    { 
     using (var client = new HttpClient()) 
     { 
      var url = "http://10.0.0.68/SET Initialization"; 
      var url2 = "http://10.0.0.68/GET Status"; 
      var response = await client.GetAsync(url); 
      Debug.WriteLine(response); 
      response = await client.GetAsync(url2); 
      Debug.WriteLine(response); 
      var result = await response.Content.ReadAsStringAsync(); 
      var jsonString = result.Substring(4); 
      var serializer = new DataContractJsonSerializer(typeof(MediaStatus)); 
      var ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)); 
      var data = (MediaStatus)serializer.ReadObject(ms); 
      Debug.Write(data.ProgNo); 
     } 
    } 
    catch (Exception exception) 
    { 
     Debug.WriteLine(exception.Message, exception.Source); 
    } 
} 

此外,該方法應該有「異步」後綴以清楚地表明,該方法的目的是異步的。同樣,我改變了HttpClient的使用方式,使其在using聲明中被包裝,因爲它實現了IDisposable接口。

如果您需要調用從事件處理程序這種方法,下面是從.Loaded事件這樣的例子:

private async void OnLoaded(object sender, RoutedEventArgs e) => 
    await common.DoSomethingAsync();