Json 反序列化不适用于 Flurl
Json Deserialization is not working with Flurl
我尝试使用来自网站的 json APIwith Flurl,但出现解析错误或转换错误。我不确定我的问题是什么,因为这是我第一次处理 json 文件。我利用以下在线 tool 从 json 文件中创建一个 C# 对象。但是当我尝试使用 Flurl 获得响应时,出现以下错误。
System.AggregateException: One or more errors occurred. ---> Flurl.Http.FlurlParsingException: Response could not be deserialized
to JSON: GET --->
Newtonsoft.Json.JsonSerializationException: Error converting value
"{"Group":[{"name":"Senior","id":1},{"name":"Age","id":1}],"Area":[{"AreaID":58,"Description":"Years
2018-19","Week":1150,"taken":true,"LDate":null","Label":"RED"}]
Path '', line 1, position 4814377. ---> System.ArgumentException: Could not cast or convert from System.String to
System.Collections.Generic.List`1[JsonTest.SeatTest].
这是失败的代码块:
var response = await url.WithHeaders(new
User_Agent = ConstantData.UserAgent,
Accept = Accept,
Referer = Referer})
..GetJsonAsync<List<SeatTest>>()
.Result;
但现在如果我使用以下内容:
var response = await url.WithHeaders(new
User_Agent = ConstantData.UserAgent,
Accept = Accept,
Referer = Referer})
.GetStringAsync()
.Result;
当我快速查看或将鼠标悬停在响应变量上时,我得到(我认为这是正常的,不确定)以下字符串。
"\"{\"Group\":[{\"name\":\"Senior\",\"id\":1},{\"name\":\"Age\",\"id\":1}],\"Area\":[{\"AreaID\":58,\"Description\":\"Years
2018-19\",\"Week\":1150,\"taken\":true,\"LDate\":null",\"Label\":\"RED\"}]
如果我应用以下内容:
var json = JsonConvert.DeserializeObject<SeatTest>(response);
它还会抛出我已经 post.
的异常
或
如果我跳过上面的行并执行以下操作:
var jSerial = new JavaScriptSerializer();
jSerial.MaxJsonLength = 50000000;
string jsonStr = jSerial.Deserialize<string>(response);
var data = jSerial.Deserialize<SeatTest>(jsonStr);
我的 class 对象显示为空。但是我没有收到任何错误或异常。
我正在使用的 Flurl 代码如下所示,或者至少是我想使用的代码:
var response = url.WithHeaders(new
{
User_Agent = ConstantData.UserAgent,
Accept = Accept,
Referer = Referer
})
.GetJsonAsync<List<SeatTest>>()
.Result;
我的对象模型如下所示:
public class SeatTest
{
[JsonProperty(PropertyName ="Group")]
public List<Group> groups { get; set; }
[JsonProperty(PropertyName = "Area")]
public List<Group> areas { get; set; }
}
[Serializable]
public class Group
{
public string name { get; set; }
public int id { get; set; }
}
[Serializable]
public class Area
{
public int AreaID{ get; set; }
public string Description { get; set; }
public int Week { get; set; }
public bool Taken { get; set; }
public DateTime LDate { get; set; }
public string Label { get; set; }
}
我希望一个对象充满了来自 API 的数据,但我得到了异常:
System.AggregateException: One or more errors occurred. ---> Flurl.Http.FlurlParsingException: Response could not be deserialized
to JSON: GET --->
Newtonsoft.Json.JsonSerializationException: Error converting value
"{"Group":[{"name":"Senior","id":1},{"name":"Age","id":1}],"Area":[{"AreaID":58,"Description":"Years
2018-19","Week":1150,"taken":true,"LDate":null","Label":"RED"}]
Path '', line 1, position 4814377. ---> System.ArgumentException: Could not cast or convert from System.String to
System.Collections.Generic.List`1[JsonTest.SeatTest].
编辑
var jSerial = new JavaScriptSerializer();
jSerial.MaxJsonLength = 50000000;
string jsonStr = jSerial.Deserialize<string>(response);
/*First pass: Here I already got the info that I need, how I map it to my class?, since I would like to use Flurl GetAsync() and map it to my object and not a string */
/*Above line response val: "\{\\"Group\\":[{\\"name\\":\\"Senior\\",\\"id\\":1},{\\"name\\":\\"Age\\",\\"id\\":2}],\\"Area\\":[{\\"AreaID\\":58,\\"Description\\":\\"Season 2018-2019\\",\\"Week\\":1150,\\"taken\\":true,\\"LDate\\":\\"2019-07-07T00:00:00\\",\\"Label\\":\\"RED\\"}]} */
/*Above line jsonStr val: null*/
var data = jSerial.Deserialize<SeatTest>(jsonStr);
/*Above line jsonStr val same as raw in postman: "\{\"Group\":[{\"name\":\"Senior\",\"id\":1},{\"name\":\"Age\",\"id\":2}],\"Area\":[{\"AreaID\":58,\"Description\":\"Season 2018-2019\",\"Week\":1150,\"taken\":true,\"LDate\":\"2019-07-07T00:00:00\",\"Label\":\"RED\"}]} */
/* data value after above line: Group: null, Area: null*/
原始邮递员Json
{
\"Group\": [
{
\"name\": \"Senior\",
\"id\": 1
},
{
\"name\": \"Adult\",
\"id\": 2
}
],
\"Area\": [
{
\"AreaID\": 58,
\"Description\": \"Area 2018-2019\",
\"Week\": 1150,
\"taken\": true,
\"LDate\": \"2019-07-07T00:00:00\",
\"Label\": \"RED\"
},
{
\"SeasonID\": 57,
\"Description\": \"Area 51\",
\"Week\": 1,
\"taken\": true,
\"LDate\": \"2019-07-015T00:00:00\",
\"Label\": \"GREEN\"
}]
}
Json 还有 JsonStr(第一关)在快速观看中的样子
{
"Group": [
{
"name": "Senior",
"id": 1
},
{
"name": "Adult",
"id": 2
}
],
"Area": [
{
"AreaID": 58,
"Description": "Area 2018-2019",
"Week": 1150,
"taken": true,
"LDate": "2019-07-07T00:00:00",
"Label": "RED"
},
{
"SeasonID": 57,
"Description": "Area 51",
"Week": 1,
"taken": true,
"LDate": "2019-07-015T00:00:00",
"Label": "GREEN"
}]
}
我们来看错误信息:
Path '', line 1, position 4814377. ---> System.ArgumentException:
Could not cast or convert from System.String to
System.Collections.Generic.List`1[JsonTest.SeatTest].
这是在告诉您 JSON 响应中的某处(确切地说是在第 4,814,377 个字符处),在 array 预期的位置有一个字符串。您似乎希望 "Group"
和 "Area"
属性都是 JSON 中的数组,但在响应的深处至少其中一个是字符串。
解决此问题的一种方法是将响应字符串解析为 JArray
并逐个构建强类型列表,同时处理解析错误:
var results = new List<SeatTest>();
var arr = JArray.Parse(response);
foreach (var obj in arr) {
try {
var seat = obj.ToObject<SeatTest>();
results.Add(seat);
}
catch (Exception ex) {
// parsing error, inspect ex and obj.ToString(). log? ignore?
}
}
我尝试使用来自网站的 json APIwith Flurl,但出现解析错误或转换错误。我不确定我的问题是什么,因为这是我第一次处理 json 文件。我利用以下在线 tool 从 json 文件中创建一个 C# 对象。但是当我尝试使用 Flurl 获得响应时,出现以下错误。
System.AggregateException: One or more errors occurred. ---> Flurl.Http.FlurlParsingException: Response could not be deserialized to JSON: GET ---> Newtonsoft.Json.JsonSerializationException: Error converting value "{"Group":[{"name":"Senior","id":1},{"name":"Age","id":1}],"Area":[{"AreaID":58,"Description":"Years 2018-19","Week":1150,"taken":true,"LDate":null","Label":"RED"}]
Path '', line 1, position 4814377. ---> System.ArgumentException: Could not cast or convert from System.String to System.Collections.Generic.List`1[JsonTest.SeatTest].
这是失败的代码块:
var response = await url.WithHeaders(new
User_Agent = ConstantData.UserAgent,
Accept = Accept,
Referer = Referer})
..GetJsonAsync<List<SeatTest>>()
.Result;
但现在如果我使用以下内容:
var response = await url.WithHeaders(new
User_Agent = ConstantData.UserAgent,
Accept = Accept,
Referer = Referer})
.GetStringAsync()
.Result;
当我快速查看或将鼠标悬停在响应变量上时,我得到(我认为这是正常的,不确定)以下字符串。
"\"{\"Group\":[{\"name\":\"Senior\",\"id\":1},{\"name\":\"Age\",\"id\":1}],\"Area\":[{\"AreaID\":58,\"Description\":\"Years 2018-19\",\"Week\":1150,\"taken\":true,\"LDate\":null",\"Label\":\"RED\"}]
如果我应用以下内容:
var json = JsonConvert.DeserializeObject<SeatTest>(response);
它还会抛出我已经 post.
的异常或
如果我跳过上面的行并执行以下操作:
var jSerial = new JavaScriptSerializer();
jSerial.MaxJsonLength = 50000000;
string jsonStr = jSerial.Deserialize<string>(response);
var data = jSerial.Deserialize<SeatTest>(jsonStr);
我的 class 对象显示为空。但是我没有收到任何错误或异常。
我正在使用的 Flurl 代码如下所示,或者至少是我想使用的代码:
var response = url.WithHeaders(new
{
User_Agent = ConstantData.UserAgent,
Accept = Accept,
Referer = Referer
})
.GetJsonAsync<List<SeatTest>>()
.Result;
我的对象模型如下所示:
public class SeatTest
{
[JsonProperty(PropertyName ="Group")]
public List<Group> groups { get; set; }
[JsonProperty(PropertyName = "Area")]
public List<Group> areas { get; set; }
}
[Serializable]
public class Group
{
public string name { get; set; }
public int id { get; set; }
}
[Serializable]
public class Area
{
public int AreaID{ get; set; }
public string Description { get; set; }
public int Week { get; set; }
public bool Taken { get; set; }
public DateTime LDate { get; set; }
public string Label { get; set; }
}
我希望一个对象充满了来自 API 的数据,但我得到了异常:
System.AggregateException: One or more errors occurred. ---> Flurl.Http.FlurlParsingException: Response could not be deserialized to JSON: GET ---> Newtonsoft.Json.JsonSerializationException: Error converting value "{"Group":[{"name":"Senior","id":1},{"name":"Age","id":1}],"Area":[{"AreaID":58,"Description":"Years 2018-19","Week":1150,"taken":true,"LDate":null","Label":"RED"}]
Path '', line 1, position 4814377. ---> System.ArgumentException: Could not cast or convert from System.String to System.Collections.Generic.List`1[JsonTest.SeatTest].
编辑
var jSerial = new JavaScriptSerializer();
jSerial.MaxJsonLength = 50000000;
string jsonStr = jSerial.Deserialize<string>(response);
/*First pass: Here I already got the info that I need, how I map it to my class?, since I would like to use Flurl GetAsync() and map it to my object and not a string */
/*Above line response val: "\{\\"Group\\":[{\\"name\\":\\"Senior\\",\\"id\\":1},{\\"name\\":\\"Age\\",\\"id\\":2}],\\"Area\\":[{\\"AreaID\\":58,\\"Description\\":\\"Season 2018-2019\\",\\"Week\\":1150,\\"taken\\":true,\\"LDate\\":\\"2019-07-07T00:00:00\\",\\"Label\\":\\"RED\\"}]} */
/*Above line jsonStr val: null*/
var data = jSerial.Deserialize<SeatTest>(jsonStr);
/*Above line jsonStr val same as raw in postman: "\{\"Group\":[{\"name\":\"Senior\",\"id\":1},{\"name\":\"Age\",\"id\":2}],\"Area\":[{\"AreaID\":58,\"Description\":\"Season 2018-2019\",\"Week\":1150,\"taken\":true,\"LDate\":\"2019-07-07T00:00:00\",\"Label\":\"RED\"}]} */
/* data value after above line: Group: null, Area: null*/
原始邮递员Json
{
\"Group\": [
{
\"name\": \"Senior\",
\"id\": 1
},
{
\"name\": \"Adult\",
\"id\": 2
}
],
\"Area\": [
{
\"AreaID\": 58,
\"Description\": \"Area 2018-2019\",
\"Week\": 1150,
\"taken\": true,
\"LDate\": \"2019-07-07T00:00:00\",
\"Label\": \"RED\"
},
{
\"SeasonID\": 57,
\"Description\": \"Area 51\",
\"Week\": 1,
\"taken\": true,
\"LDate\": \"2019-07-015T00:00:00\",
\"Label\": \"GREEN\"
}]
}
Json 还有 JsonStr(第一关)在快速观看中的样子
{
"Group": [
{
"name": "Senior",
"id": 1
},
{
"name": "Adult",
"id": 2
}
],
"Area": [
{
"AreaID": 58,
"Description": "Area 2018-2019",
"Week": 1150,
"taken": true,
"LDate": "2019-07-07T00:00:00",
"Label": "RED"
},
{
"SeasonID": 57,
"Description": "Area 51",
"Week": 1,
"taken": true,
"LDate": "2019-07-015T00:00:00",
"Label": "GREEN"
}]
}
我们来看错误信息:
Path '', line 1, position 4814377. ---> System.ArgumentException: Could not cast or convert from System.String to System.Collections.Generic.List`1[JsonTest.SeatTest].
这是在告诉您 JSON 响应中的某处(确切地说是在第 4,814,377 个字符处),在 array 预期的位置有一个字符串。您似乎希望 "Group"
和 "Area"
属性都是 JSON 中的数组,但在响应的深处至少其中一个是字符串。
解决此问题的一种方法是将响应字符串解析为 JArray
并逐个构建强类型列表,同时处理解析错误:
var results = new List<SeatTest>();
var arr = JArray.Parse(response);
foreach (var obj in arr) {
try {
var seat = obj.ToObject<SeatTest>();
results.Add(seat);
}
catch (Exception ex) {
// parsing error, inspect ex and obj.ToString(). log? ignore?
}
}