反序列化JSON对象xamarin C#

时间:2017-07-04 06:51:06

标签: c# .net json xamarin serialization

在反序列化JSON对象时,我在Xamarin交叉平台中收到以下错误。我试着用字典做。但是,一切都给了我同样的例外。

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": "rokesh@geoit.in",
  "phone": null,
  "current_group": "11",
  "user_groups": {
   "11": "Parent"
   }
},
"error": false
}}

请帮我解决这个问题。

谢谢, Rokesh

3 个答案:

答案 0 :(得分:1)

字符串与您尝试反序列化的对象之间存在不匹配。 data对象不是一个数组,并且有一个额外的嵌套对象,它没有在JSON中单独命名,包含msg字段和user数据,但是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‌​sh@geoit.in\",\"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; }
}

答案 1 :(得分:0)

它应该是一个数组,开始和结束括号应该是方括号:

<强> [

{ "msg": null,"data":

[ {           “名字”:“地理”,           “email”:“rokesh@geoit.in”,           “电话”:null,           “current_group”:“11”,           “user_groups”:

<强> [ {            “11”:“父母”            } 的

} 的

“错误”:false         }

<强>

同样在您的代码中,您不需要var jObject = JObject.Parse(readHttpResponse);,因为readHttpResponse已经是一个JSON字符串,您可以将其反序列化为对象。

答案 2 :(得分:0)

早先对误导性答案的态度。您需要制作数组的对象是数据&#39;响应JSON的属性。您必须从服务器端获取Domainmodal List<User>。您应该从这个fiddle

中更好地理解

readHttpResponse可以是

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

readHttpResponse.data需要是数组

[{
              "name": "geoit",
              "email": "rokesh@geoit.in",
              "phone": null,
              "current_group": "11",
              "user_groups": {
               "11": "Parent"
               }
            }]