【问题标题】:Cannot deserialize the current JSON array with metadata and records无法使用元数据和记录反序列化当前 JSON 数组
【发布时间】:2017-05-27 16:56:00
【问题描述】:

这是我从 Web 服务返回的 JSON 数据示例。

它有一个“odata.metadata”的单个节点,另一个“value”的单个节点,然后是由“Code”、“Name”和“XTag”3个字段组成的重复记录。这是在一个名为 Content

的字符串变量中
{"odata.metadata":"https://notthereal.domain:3148/system/OData/$metadata#pageLocationList","value":[{"Code":"LOC-A","Name":"Location A","XTag":"36;DgAAAAJ7/zEAMAAwAC0ATQBBAEkATgAAAAAA8;264943250;"},{"Code":"LOC-B","Name":"Location B","XTag":"36;DgAAAAJ7/zEAMAAxAC0ATQBBAEkATgAAAAAA8;388906690;"},{"Code":"LOC-C","Name":"Location C","XTag":"36;DgAAAAJ7/zEAMAAyAC0ATQBBAEkATgAAAAAA8;388844480;"},{"Code":"LOC-D","Name":"Location D","XTag":"36;DgAAAAJ7/zEAMAAzAC0ATQBBAEkATgAAAAAA8;388876720;"}]}

我有以下作为模型,是通过将 JSON 数据粘贴到类中得到的。

public class ModelPageLocationList
{
    public string odatametadata { get; set; }
    public List<Value> value { get; set; }
}

public class Value
{
    public string Code { get; set; }

    public string Name { get; set; }

    public string XTag { get; set; }
}

这是试图反序列化它的代码...

DataPageLocationList = 
JsonConvert.DeserializeObject<List<ModelPageLocationList>>(content);

..这是错误消息。我被困住了!有任何想法吗?我认为问题在于开始时的 2 条单条记录,然后是之后的重复数据。

ERROR Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.

这就是我所说的

public async Task<List<ModelPageLocationList>> RefreshPageLocationListAsync ()
    {
        DataPageLocationList = new List<ModelPageLocationList>();

        var uri = new Uri(string.Format(WebServiceSettings.WebServiceUrl, string.Empty));

        try
        {
            var response = await client.GetAsync(uri);
            if (response.IsSuccessStatusCode)
            {
                var content = await response.Content.ReadAsStringAsync();
                Debug.WriteLine("{0}", content.ToString());

                DataPageLocationList = JsonConvert.DeserializeObject<List<ModelPageLocationList>>(content);

            }
        } catch (Exception ex)
        {
            Debug.WriteLine(@"ERROR {0}", ex.Message);
        }

        return (DataPageLocationList); 
    }

【问题讨论】:

  • 你能分享你试图反序列化的 JSON 吗?
  • 这是帖子的第一行

标签: c# json json.net metadata json-deserialization


【解决方案1】:

两件事。使用JsonProperty 处理odata.metadata 属性,因为属性名称中的点(.)会导致语法问题。

public class ModelPageLocationList {
    [JsonProperty("odata.metadata")]
    public string odatametadata { get; set; }
    [JsonProperty("value")]
    public List<Value> value { get; set; }
}

接下来根据提供的 JSON 示例数据你需要重构调用代码

public async Task<ModelPageLocationList> RefreshPageLocationListAsync () {
    try {
        var uri = new Uri(string.Format(WebServiceSettings.WebServiceUrl, string.Empty));
        var response = await client.GetAsync(uri);
        if (response.IsSuccessStatusCode) {
            var result = await response.Content.ReadAsAsync<ModelPageLocationList>();
            return result;
        }
    } catch (Exception ex) {
        Debug.WriteLine(@"ERROR {0}", ex.Message);
    }
    return null; 
} 

【讨论】:

  • 我没有 Content.ReadAsAsync 作为选项。
  • System.Net.Http.Formatting.dll中的扩展方法
  • 所以您的解决方案中没有 JsonConvert?
  • @DarrellUK 它在后台使用 JsonConvert 作为依赖项
【解决方案2】:

您需要序列化到您的根对象ModelPageLocationList,而不是您的根对象列表。您的 JSON 是一个对象而不是对象数组。这将解决它:

DataPageLocationList = 
    JsonConvert.DeserializeObject<ModelPageLocationList>(content);

【讨论】:

  • 我收到一个错误“无法将类型'App.ModelPageLocationList'隐式转换为'System.Collections.Generic.List'
  • @DarrellUK:是的,那只是你在 C# 中为你的变量使用了错误的类型,DataPageLocationList a ModelPageLocationList 不是ModelPageLocationList 的列表。
【解决方案3】:

没有看到您尝试传递的 JSON 数据,我只能根据您提供的信息提供两个可能的答案。

1) 确保您的 JSON 如下所示:

{
    "odatametadata": "SomeDataHere",
    "value": [{
            "code": "Code1",
            "name": "Name1",
            "xTag": "XTag1"
        }, {
            "code": "Code1",
            "name": "Name1",
            "xTag": "XTag1"
        }, {
            "code": "Code1",
            "name": "Name1",
            "xTag": "XTag1"
        },
    ]
}

2 将此属性添加到您的 C# 类模型中

public class ModelPageLocationList
{
    [JsonProperty("odatametadata")]
    public string odatametadata { get; set; }
    [JsonProperty("value")]
    public List<Value> value { get; set; }
}

public class Value
{
    [JsonProperty("code")]
    public string Code { get; set; }
    [JsonProperty("name")]
    public string Name { get; set; }
    [JsonProperty("xTag")]
    public string XTag { get; set; }
}

【讨论】:

  • (这是帖子的第一行,我无法控制收到的数据)。
【解决方案4】:

我执行了以下操作,以使我的代码在我的帖子开头使用 JSON 数据。不理想,我希望能够做到这一点而不必编辑 JSON 字符串。

public async Task<List<ModelPageLocationList>> RefreshPageLocationListAsync ()
    {
        DataPageLocationList = new List<ModelPageLocationList>();
        var uri = new Uri(string.Format(WebServiceSettings.WebServiceUrl, string.Empty));

        try
        {
            var response = await client.GetAsync(uri);
            if (response.IsSuccessStatusCode)
            {
                var content = await response.Content.ReadAsStringAsync();
                Debug.WriteLine("BEFORE {0}", content.ToString());

                content = content.Substring(content.IndexOf('['), content.IndexOf(']') - content.IndexOf('[') + 1);
                Debug.WriteLine("AFTER {0}", content.ToString());

                DataPageLocationList = JsonConvert.DeserializeObject<List<ModelPageLocationList>>(content);
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine(@"ERROR {0}", ex.Message);
        }
        return (DataPageLocationList);
    }

以及来自 JSON 数据的类

public class ModelPageLocationList
{
    public string Code { get; set; }

    public string Name { get; set; }

    public string ETag { get; set; }
}

感谢大家的回复。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-12
    • 2017-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多