尝试反序列化多维数组时出现Newtonsoft JSON JsonReaderException



我的应用程序中有一个脚本,它从我的PHP REST API收集一些JSON数据。API使用json_encode()对其生成的多维数组进行序列化。我的应用程序中的脚本应该将其反序列化为C#中的等效代码,这样我就可以在每个子数组表示";行";数据库中的信息。然而,我遇到了这个错误:

Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: A. Path '', line 0, position 0.
at Newtonsoft.Json.JsonTextReader.ParseValue () [0x002b3] in <2073514815234917a5e8f91b0b239405>:0 
at Newtonsoft.Json.JsonTextReader.Read () [0x0004c] in <2073514815234917a5e8f91b0b239405>:0 
at Newtonsoft.Json.JsonReader.ReadAndMoveToContent () [0x00000] in <2073514815234917a5e8f91b0b239405>:0 
at Newtonsoft.Json.JsonReader.ReadForType (Newtonsoft.Json.Serialization.JsonContract contract, System.Boolean hasConverter) [0x0004a] in <2073514815234917a5e8f91b0b239405>:0 
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Boolean checkAdditionalContent) [0x000db] in <2073514815234917a5e8f91b0b239405>:0 
at Newtonsoft.Json.JsonSerializer.DeserializeInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType) [0x

JSON(与我的应用程序从服务器接收到的一样(

[{"type":"0","ID":"1","groupID":"0","authorID":"14","contents":"rfgwgfgdfssd","time_stamp":"0-0-0"}, {"type":"0","ID":"2","groupID":"0","authorID":"14","contents":"whwrgthwr","time_stamp":"0-0-0"}]

脚本

async void getUpdatesAsync()
{
Console.WriteLine("starting...");
BackendConnect connectionHandler = new BackendConnect("vocal/posts/index.php");
var updatesRequestInfo = new Dictionary<string, string>
{
{"sessionID", "c1f7a973c04e18a05342ecc2d16f7339"},
{"type", "updateFeed"},
{"userID", "14"}
};
connectionHandler.addData(updatesRequestInfo);
string updatesReturn = await connectionHandler.sendForm(); // returns the json
Console.WriteLine(updatesReturn); // the above json was copied and pasted from this output
List<Dictionary<string, string>> updatesArray = JsonConvert.DeserializeObject<List<Dictionary<string, string>>>(updatesReturn); // this line causes error
Console.WriteLine(updatesArray);
//updatesArray.ForEach(Console.WriteLine);
}

我的应用程序中的另一个脚本也使用JsonConvert.DeserializeObject<DataType>(stringToDeserialize),当将一维数组(["SUCCESS", "adlhfbaf"](提供给反序列化函数时,它可以工作,并能够将其解析为一个简单的列表,但在尝试使用上面的多维数组JSON时失败。

到目前为止,我已经尝试将updatesArray变量设置为无数不同的数据类型,看看这是否是我怀疑的问题,但作为像C#这样必须预先定义数据类型的语言的新手,我很难解决这个问题。

从本质上讲,我想将它作为C#中的字典列表导入,这样我就可以使用foreach()循环遍历初始列表的每个索引,并恢复一个字典,在那里我可以获取特定的值(如内容(。下面是一个我想要导入的示例(我知道不正确的语法,但至少是一个粗略的想法(

var updatesArray = new List<Dictionary<string, string>>
{
{
{"type", "0"},
{"ID", "1"},
{"groupID", "0"},
{"authorID", "14"},
{"contents", "rfgwgfgdfssd"},
{"time_stamp", "0-0-0"}
},
{
{"type", "0"},
{"ID", "2"},
{"groupID", "0"},
{"authorID", "14"},
{"contents", "whwrgthwr"},
{"time_stamp", "0-0-0"}
}
};

而不是反序列化到字典中。为你的回应创建一个模型。然后将其反序列化为该模型的List。你可以在下面看到一个例子。我基于您提供的代码,刚刚用一个变量替换了所有的调用,该变量包含一个JSON字符串,就像您从调用中获得的那样

public static void Main()
{
{       
//json string
//you should fix the timestamp coming back...not a real timestamp
var testresponse = "[{"type":"0","ID":"1","groupID":"0","authorID":"14","contents":"rfgwgfgdfssd","time_stamp":"0-0-0"},{"type":"0","ID":"2","groupID":"0","authorID":"14","contents":"whwrgthwr","time_stamp":"0-0-0"}]";
Console.WriteLine(testresponse);
var updatesArray = JsonConvert.DeserializeObject<List<TestModel>>(testresponse);
Console.WriteLine(updatesArray[0].Id);
Console.WriteLine(updatesArray[1].Id);

var after = JsonConvert.SerializeObject(updatesArray);

Console.WriteLine(after);
}
}

如果时间戳是DateTime,则将数据类型设置为DateTime,但您需要从服务器发送真实的DateTime

public class TestModel
{
[JsonProperty(PropertyName = "type")]
public int Type { get; set; }
[JsonProperty(PropertyName = "ID")]
public int Id {get; set;}
[JsonProperty(PropertyName = "groupID")]
public int GroupId {get; set;}
[JsonProperty(PropertyName = "authorID")]
public int AuthorId {get; set;}
[JsonProperty(PropertyName = "contents")]
public string Contents {get; set;}
[JsonProperty(PropertyName = "time_stamp")]
public string TimeStamp {get; set;}
}

我的问题

非常感谢所有试图解决我问题的人。我觉得自己很愚蠢,现在我已经解决了xD问题。非常感谢@Jason,他提到用十六进制查看我的变量内容。我写了几行将变量转换为Hex,复制了这个输出,并将其放入在线的Hex-to-ASCII转换器中,发现我误读了程序的输出,并且忽略了PHP脚本返回的两倍多的数据量,这是由于测试中PHP中留下了一个无赖的print_r()命令,该命令在数组被JSON编码之前输出了数组:

Array
(
[0] => Array
(
[type] => 0
[ID] => 1
[groupID] => 0
[authorID] => 14
[contents] => rfgwgfgdfssd
[time_stamp] => 0-0-0
)
[1] => Array
(
[type] => 0
[ID] => 2
[groupID] => 0
[authorID] => 14
[contents] => whwrgthwr
[time_stamp] => 0-0-0
)
)
[{"type":"0","ID":"1","groupID":"0","authorID":"14","contents":"rfgwgfgdfssd","time_stamp":"0-0-0"},{"type":"0","ID":"2","groupID":"0","authorID":"14","contents":"whwrgthwr","time_stamp":"0-0-0"}]

而不仅仅是:

[{"type":"0","ID":"1","groupID":"0","authorID":"14","contents":"rfgwgfgdfssd","time_stamp":"0-0-0"},{"type":"0","ID":"2","groupID":"0","authorID":"14","contents":"whwrgthwr","time_stamp":"0-0-0"}]

总结的其他有用的可能问题

为了在未来帮助他人,我认为我也应该提到我从这个线程中学到的一些东西——可能是那个错误的问题。

流氓字节顺序标记/零宽度空间

  • 在C#中,像这样的Unicode字符可以通过String.Trim()函数删除
  • 零宽度空间在unicode中始终表示为U+200B
  • 字节顺序标记根据所使用的编码进行更改。对于UTF-16,BOM字符表示为U+FEFF
  • 这意味着这个问题的解决方案是myString = myString.Trim(new char[]{'uFEFF','u200B'});

不正确的数据类型/不确定要使用的数据类型

  • 创建适合您需要的结构的自己的对象(如上面@ejwill的帖子所示(
  • 反序列化到此结构

从不同命名空间意外导入的列表/字典

  • 确保导入的模块都没有List或Dictionary的定义
  • 如果他们这样做了,你可以:
  • 缩短include,以便只包含该模块中需要的对象(IE:using System.Text;而不是using System;(
  • 或者将名称空间添加到List/Dictionary声明的前面(IE:System.Collections.Generic.List<string>,而不仅仅是List<string>(

相关内容

  • 没有找到相关文章

最新更新