Newtonsoft.Json无法从JSON转换为ICollection <object>

时间:2019-03-04 09:10:33

标签: c# .net-core json.net

嗨,我有以下JSON,并想反序列化为ICollection<Location>

  

“ \ u0001 [{\” Id \“:1,\”名称\“:\” A-01 \“,\”地址\“:\” aa \“,   \“儿童\”:[{\“ Id \”:2,\“名称\”:\“ A-01-01 \”,\“地址\”:\“ bb \”,   \“儿童\”:[{\“ Id \”:5,\“名称\”:\“ A-01-02-01 \”,\“地址\”:   \“ cc \”}]},{\“ Id \”:3,\“名称\”:\“ A-01-02 \”,\“地址\”:\“ dd \”}]},   {\“ Id \”:4,\“名称\”:\“ B-01 \”,\“地址\”:\“ ee \”,\“儿童\”:   [{\“ Id \”:6,\“名称\”:\“ B-01-01 \”,\“地址\”:\“ ff \”}]}]“”

可读JSON

[
  {
    "Id": 1,
    "Name": "A-01",
    "Address": "aa",
    "Children": [
      {
        "Id": 2,
        "Name": "A-01-01",
        "Address": "bb",
        "Children": [
          {
            "Id": 5,
            "Name": "A-01-02-01",
            "Address": "cc"
          }
        ]
      },
      {
        "Id": 3,
        "Name": "A-01-02",
        "Address": "dd"
      }
    ]
  },
  {
    "Id": 4,
    "Name": "B-01",
    "Address": "ee",
    "Children": [
      {
        "Id": 6,
        "Name": "B-01-01",
        "Address": "ff"
      }
    ]
  }
]

位置对象

public class Location
{
    [JsonProperty("Id")]
    public int Id { get; set; }

    [JsonProperty("Name")]
    [Required]
    public string Name { get; set; }

    [JsonProperty("Address")]
    public string Address { get; set; }

    public ICollection<Asset> Assets { get; set; }

    public Location ParentLocation { get; set; }

    [JsonProperty("Children")]
    public virtual ICollection<Location> ChildrenLocation { get; set; }

}

我尝试测试清理字符串,但没有希望。

    var jsonString = @"[{""Id"":1,""Name"":""A-01"",""Address"":""aa"",""Children"":[{""Id"":2,""Name"":""A-01-01"",""Address"":""bb",""Children"":[{""Id"":5,""Name"":""A-01-02-01"",""Address"":""cc""}]},{""Id"":3,""Name"":""A-01-02"",""Address"":""dd""}]},{""Id"":4,""Name"":""B-01"",""Address"":""ee"",""Children"":[{""Id"":6,""Name"":""B-01-01"",""Address"":""ff""}]}]";

    var locations = JsonConvert.DeserializeObject<ICollection<Location>>(jsonString.Trim());

错误

Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: . Path '', line 0, position 0.
   at Newtonsoft.Json.JsonTextReader.ParseValue()
   at Newtonsoft.Json.JsonTextReader.Read()
   at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value)

2 个答案:

答案 0 :(得分:2)

错误很明显,字符串不是有效的JSON,问题出在第一个字符\u0001上。

“可读” JSON字符串和修剪测试不包含该字符,因此甚至无法重现该问题。

Trim()也不能单独工作。它的工作是删除空格,但是\u0001是SOH(标头开始)字符。那不是 空格。

要真正解决该问题,应该修复产生此字符的代码,以使其发出该字符。如果该JSON行来自使用SOH作为记录传递者的流JSON文件,则应对其进行修复,以使其在JSON字符串中包含记录定界符。

如果这不可能,则应使用String.Trim(Char[])重载来删除SHO字符:

var locations = JsonConvert.DeserializeObject(jsonString.Trim('\u0001'));

一旦删除了SOH字符,反序列化就可以了:

var jsonString = "\u0001[{\"Id\": 1, \"Name\": \"A-01\", \"Address\": \"aa\", \"Children\": [{\"Id\": 2, \"Name\": \"A-01-01\", \"Address\": \"bb\", \"Children\": [{\"Id\": 5, \"Name\": \"A-01-02-01\", \"Address\": \"cc\"}]}, {\"Id\": 3, \"Name\": \"A-01-02\", \"Address\": \"dd\"}]}, {\"Id\": 4, \"Name\": \"B-01\", \"Address\": \"ee\", \"Children\": [{\"Id\": 6, \"Name\": \"B-01-01\", \"Address\": \"ff\"}]}]";
var cleaned=jsonString.Trim('\u0001');
var locations = (JArray)JsonConvert.DeserializeObject(cleaned);
Debug.Assert(locations.Count==2);

var address=(JValue)locations[1]["Children"][0]["Address"];
Debug.Assert(String.Equals(address.Value,"ff"));

答案 1 :(得分:0)

如Dai所说,有一个“ \ u0001”字符(请参见description)。我认为您是从somwehere复制它的,不需要它,因此可以将其删除:

  var str =
                "\u0001[{\"Id\": 1, \"Name\": \"A-01\", \"Address\": \"aa\", \"Children\": [{\"Id\": 2, \"Name\": \"A-01-01\", \"Address\": \"bb\", \"Children\": [{\"Id\": 5, \"Name\": \"A-01-02-01\", \"Address\": \"cc\"}]}, {\"Id\": 3, \"Name\": \"A-01-02\", \"Address\": \"dd\"}]}, {\"Id\": 4, \"Name\": \"B-01\", \"Address\": \"ee\", \"Children\": [{\"Id\": 6, \"Name\": \"B-01-01\", \"Address\": \"ff\"}]}]";
            var unescapeStr = str.Replace("\u0001", String.Empty);
            var result = JsonConvert.DeserializeObject<ICollection<Location>>(unescapeStr);

字符“ \ u0001”根本不应该出现在字符串中,不仅仅是在开始时,因此您必须使用“替换而非修剪”将其从所有字符串中删除

测试代码中的第二个问题。当您复制\带有某些特殊字符的字符串时,Visual Studio会询问您是否要对其进行转义,如果您说“是”,则可以转义两次字符

因此,请尝试使用上面示例中的字符串进行测试