2016-07-06 77 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();