2017-07-04 167 views
1

在反序列化JSON对象时,Xamarin跨平台中出现以下错误。我试图用字典来做。但是,一切都给了我同样的例外。反序列化JSON对象xamarin C#

Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON object (e.g. {\"name\":\"value\"}) into type 'System.Collections.Generic.List`1[NBStudents.Models.jsonobjectclass+User]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly. 
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.Path 'data.name', line 4, position 11. 

我的JSON对象类:

public class jsonobjectclass 
{ 
    public class User 
    { 
     public string name { get; set; } 
     public string email { get; set; } 
     public string phone { get; set; } 
     public string current_group { get; set; } 
     public List<UserGroups> user_groups { get; set; } 
    } 

    public class UserGroups 
    { 
     [JsonProperty("10")] 
     public string Student { get; set; } 
     [JsonProperty("15")] 
     public string Tutor { get; set; } 
     [JsonProperty("11")] 
     public string Parent { get; set; } 
    } 

    public class Token 
    { 
     public string access_token { get; set; } 
     public int expires_in { get; set; } 
     public string token_type { get; set; } 
     public string scope { get; set; } 
     public string refresh_token { get; set; } 
     public string error { get; set; } 
    } 


    public class UserResponse 
    { 
     public string msg { get; set; } 
     public List<User> data { get; set; } 
     public bool error { get; set; } 
    } 
} 

我的代码进行反序列化JSON:

public static async Task<jsonobjectclass.UserResponse> UserRetrievalTask(string token, string apiUrl) 
    { 
     var jsonObject = new jsonobjectclass.UserResponse(); 
     string readHttpResponse; 

     using (var httpClient = new HttpClient()) 
     { 
      using (var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, apiUrl)) 
      { 
       httpRequestMessage.Headers.Add("Authorization", "Bearer " + token); 
       using (var httpResponse = await httpClient.SendAsync(httpRequestMessage).ConfigureAwait(false)) 
       { 
        readHttpResponse = await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); 
        var jObject = JObject.Parse(readHttpResponse); 
        try 
        { 
         jsonObject = JsonConvert.DeserializeObject<jsonobjectclass.UserResponse>(jObject.ToString()); 
        } 
        catch(Exception ex) 
        { 
         string excep = ex.ToString(); 
         readHttpResponse = excep; 
        } 
       } 
      } 
     } 
     return jsonObject; 
    } 

我的JSON字符串:

{{ 
    "msg": null, 
    "data": { 
    "name": "geoit", 
    "email": "[email protected]", 
    "phone": null, 
    "current_group": "11", 
    "user_groups": { 
    "11": "Parent" 
    } 
}, 
"error": false 
}} 

请帮我解决这个问题。

谢谢, Rokesh

+0

张贴您的json字符串 – HeisenBerg

+2

阅读[问]并创建一个[mcve]。所有的HTTP代码都是不相关的,相关的部分,即JSON字符串,不在你的问题中。 – CodeCaster

+0

在获得响应后向我们显示readHttpResponse的值 –

回答

1

你有字符串,你试图反序列化到对象之间的不匹配。所述data对象不是数组并且存在未在单独含有msg字段和user数据的JSON命名的附加嵌套对象,但error字段不是该对象的一部分:

正如注释具有指出JSON是无效的,所以如果你有控制源,我会解决这个问题。

如果没有,你可以实现一个阅读器和解析它的令牌标志,是这样的:

using (var response = await client.GetAsync(_url, HttpCompletionOption.ResponseHeadersRead)) 
using (var stream = await response.Content.ReadAsStreamAsync()) 
using (var streamReader = new StreamReader(stream)) 
using (var reader = new JsonTextReader(streamReader)) 
{ 

    var serializer = new JsonSerializer();  

    while (reader.Read()) 
    { 
     switch (reader.TokenType) 
     { 
      case JsonToken.Start: 
      // code to handle it 
      break; 
      case JsonToken.PropertyName: 
      // code to handle it 
      break; 

      // more options 
     } 
    }  
} 

虽然这种做法是比较脆弱的。您可以查看The JSON.Net JsonToken docs了解更多信息。基于

您的评论和使用https://jsonlint.com/响应字符串

"{\"msg\":null,\"data\":{\"name\":\"geoit\",\"email\":\"roke‌​[email protected]\",\"phon‌​e\":null,\"current_g‌​roup\":\"11\",\"user‌​_groups\":{\"11\":\"‌​Parent\"}},\"error\"‌​:false}" 

实际上是有效的JSON,但对象是有点匪夷所思。我认为它看起来像这样在C#

public class UserGroup 
{ 
    public string 11 { get; set; } 
} 

public class UserData { 
    public string name { get; set; } 
    public string email { get; set; } 
    public string phone { get; set; } 
    public string current_group { get; set; } 
    public UserGroup user_groups { get; set; } 
} 

public class ResponseObject 
{  
    public string msg { get; set; } 
    public UserData data { get; set; } 
    public bool error { get; set; } 
} 
+0

哇...!它真的为我工作,感谢兄弟... :-) – Rokesh

+0

令牌方法或C#对象?虽然它是有效的JSON/C#POCOs我不禁想到源不正确序列化。拥有“11”的属性只是很奇怪 –

+0

是的,最主要的是我应该使用类对象'公共UserData数据{获取;组; }'而不是List数组'列表 data {get;组; }'...太好了!谢谢!! – Rokesh

0

它应是一个阵列的开闭括号应该是方括号:

[

{ "msg": null,"data": 

[ { “名称”: “geoit”, “email”:“[email protected]”, “phone”:null, “current_group”: “11” 时, “user_groups”:

[ { “11”: “母体” } ]

} ]

“错误”:错误 }

]

而且在你的代码,你不需要var jObject = JObject.Parse(readHttpResponse);因为readHttpResponse已经是你可以deserialzie为对象的JSON字符串。

+0

此线'readHttpResponse =等待httpResponse.Content.ReadAsStringAsync()ConfigureAwait( false);''给我输出为'“{\”msg \“:null,\”data \“:{\”name \“:\”geoit \“,\”email \“:\”rokesh @ geoit。在\”,\ “电话\”:空,\ “current_group \”:\ “11 \”,\ “user_groups \”:{\ “11 \”:\ “父\”}} \ “错误\” :false}“' – Rokesh

+0

This line'var jObject = JObject.Parse(readHttpResponse);'give me'{{ “msg”:null, “data”:{ “name”:“geoit”, “email”:“rokesh @ geoit。在” “手机”:空, “current_group”: “11”, “user_groups”:{ “11”: “父” } }, “错误”:假​​ }}' – Rokesh

+0

所以如何更改外部{}到[] ... ?? – Rokesh

0

以前的误导性答案的范围。您需要创建数组的对象是响应JSON的'data'属性。您必须从服务器端获取它作为Domainmodal List<User>。你应该从这个fiddle

readHttpResponse更好的理解可以

{ 
      "msg": null, 
      "data": [{ 
      "name": "geoit", 
      "email": "[email protected]", 
      "phone": null, 
      "current_group": "11", 
      "user_groups": { 
      "11": "Parent" 
      } 
     }], 
     "error": false 
    } 
and 

readHttpResponse.data需求是数组

[{ 
       "name": "geoit", 
       "email": "[email protected]", 
       "phone": null, 
       "current_group": "11", 
       "user_groups": { 
       "11": "Parent" 
       } 
      }] 
+0

我仅以{{}}形式接收它@Jins。因为我没有访问服务器..有没有办法将代码中的外部{}更改为[]? – Rokesh

+0

你没有访问服务器?如果您的预期结果需要一个数组,您可以建议服务器组将其设置为数组。 –

+0

雅高级开发人员只给我提出了请求url和JSON方法。 – Rokesh