嗨,我有以下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)
答案 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会询问您是否要对其进行转义,如果您说“是”,则可以转义两次字符
因此,请尝试使用上面示例中的字符串进行测试