Json反序列化不适用于Flurl

时间:2019-07-26 16:23:02

标签: c# json rest javascriptserializer flurl

我尝试从网站使用带有Flurl的json API,但遇到解析错误或转换错误。我不确定是什么问题,因为这是我第一次处理json文件。我利用以下在线tool从json文件中创建一个C#对象。但是,当我尝试通过Flurl获得响应时,会出现以下错误。

  

System.AggregateException:发生一个或多个错误。 ---> Flurl.Http.FlurlParsingException:无法反序列化响应   到JSON:GET --->   Newtonsoft.Json.JsonSerializationException:转换值时出错   “ {” Group“:[{” name“:” Senior“,” id“:1},{” name“:” Age“,” id“:1}],” Area“:[{” AreaID“: 58,“描述”:“年份   2018-19“,” Week“:1150,” taken“:true,” LDate“:null”,“ Label”:“ RED”}]

     

路径'',第1行,位置4814377。---> System.ArgumentException:无法将System.String强制转换或转换为   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 \\“ :\\“年份   2018-19 \\“,\\” Week \\“:1150,\\” taken \\“:true,\\” LDate \\“:null”,\\“ Label \\”:\\“ RED \\“}]

如果我应用以下内容:

var json = JsonConvert.DeserializeObject<SeatTest>(response);

它还会抛出我已经发布的异常。

OR

如果我跳过上面的行并执行以下操作:

var jSerial = new JavaScriptSerializer();
jSerial.MaxJsonLength = 50000000;
string jsonStr = jSerial.Deserialize<string>(response); 
var data = jSerial.Deserialize<SeatTest>(jsonStr);

我的班级对象显示为空。但是我没有任何错误或异常。

我正在使用的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:发生一个或多个错误。 ---> Flurl.Http.FlurlParsingException:无法反序列化响应   到JSON:GET --->   Newtonsoft.Json.JsonSerializationException:转换值时出错   “ {” Group“:[{” name“:” Senior“,” id“:1},{” name“:” Age“,” id“:1}],” Area“:[{” AreaID“: 58,“描述”:“年份   2018-19“,” Week“:1150,” taken“:true,” LDate“:null”,“ Label”:“ RED”}]

     

路径'',第1行,位置4814377。---> System.ArgumentException:无法将System.String强制转换或转换为   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*/

原始邮递员杰森

{
   \"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"
        }]
}

1 个答案:

答案 0 :(得分:0)

让我们看看错误消息:

  

“路径”,第1行,位置4814377。---> System.ArgumentException:   无法将System.String强制转换或转换为   System.Collections.Generic.List`1 [JsonTest.SeatTest]。

这是告诉您JSON响应中的某个位置(确切地说是第4,814,377个字符),在数组中应有一个字符串。看来您期望"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?
    }
}