将可能是单个 T 对象或 T 数组的 JSON 反序列化为 List<T>。

5

我有如下代码:

var json = GetJsonData(path);
JObject event_dates_data = JObject.Parse(json);
var event_dates_list = JObject.Parse(event_dates_data["document"]["date"].ToString());
var event_dates = JsonConvert.DeserializeObject<List<EventDate>>(event_dates_list.ToString());

JSON可能包含一个对象数组(例如 "date:[{}, {},{}] ")或只有一个对象(例如 "date:{}")

Json的格式如下:

{
"document": {
"result": "success",
"resultcode": "000000",
"note": null,
"totaldates": "1",
"date": {
  "date_id": "351314",
  "live": "n",
  "datestart": "2012-03-07",
  "dateend": "2015-03-07",
  "timestart": "12:00",
  "timeend": "14:00",
  "date_available": "10000"
}
}
}

或者:

{
"document": {
"result": "success",
"resultcode": "000000",
"note": null,
"totaldates": "4",
"date": [
  {
    "date_id": "346022",
    "live": "n",
    "datestart": "2011-02-19",
    "dateend": "2011-02-19",
    "timestart": "12:00",
    "timeend": "14:00",
    "date_available": "10000"
  },
  {
    "date_id": "346023",
    "live": "n",
    "datestart": "2011-02-20",
    "dateend": "2011-02-20",
    "timestart": "12:00",
    "timeend": "14:00",
    "date_available": "10000"
  },
  {
    "date_id": "346024",
    "live": "n",
    "datestart": "2011-02-21",
    "dateend": "2011-02-21",
    "timestart": "12:00",
    "timeend": "14:00",
    "date_available": "10000"
  },
  {
    "date_id": "546580",
    "live": "y",
    "datestart": "2015-08-15",
    "dateend": "2015-08-15",
    "timestart": "12:00",
    "timeend": "14:00",
    "date_available": "10000"
  }
]
}
}

我有关于“date”的poco:

public class EventDate {

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


    [JsonProperty("live")]
    [JsonConverter(typeof(AvailableForSalesFiledConverter))]
    public bool AvailableForSales { get; set; }


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


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


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


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


    [JsonProperty("date_available")]
    public int DateAvailable { get; set; }
}

当我尝试反序列化时出现异常: “无法将当前JSON对象(例如{\"name\":\"value\"})反序列化为类型'System.Collections.Generic.List`1[TicketProvider.BrownPaperTickets.Entities.EventDate]',因为该类型需要一个JSON数组(例如[1,2,3])才能正确反序列化。\r\n要解决此错误,请将JSON更改为JSON数组(例如[1,2,3])或更改反序列化类型,使其成为普通的.NET类型(例如不是像整数这样的原始类型,也不是像数组或列表这样的集合类型)可以从JSON对象反序列化。JsonObjectAttribute也可以添加到类型中,以强制从JSON对象反序列化。\r\n路径'date_id',行2,位置13。” 如何将它转换为List?
3个回答

1
var json = GetJsonData(path);
JObject event_dates_data = JObject.Parse(json);
var event_dates_list = JObject.Parse(event_dates_data["document"]["date"].ToString());
event_dates_list = string.Format("[{0}]", event_dates_list.Trim('[', ']'));
var event_dates = JsonConvert.DeserializeObject<List<EventDate>>(event_dates_list.ToString());

当然可以运行。但我认为Json.Net库应该有一些标准方法。 - Vitach
3
使用JsonConverter比手动操作JSON并重新解析它要好得多。请参考链接的重复问题和答案。 - Brian Rogers

0

我有点困惑,因为你似乎在那里做了一些混杂的事情。

我建议你创建一个POCO对象,将你的数据表示为一个类。它应该有一个DateTime类型的列表和一个EventDate类型的列表,当你序列化时,你只需要将整个类序列化为:

var my_poco = // create your object here;
var poco_as_json = Newtonsoft.Json.JsonConvert.SerializeObject(my_poco);

// You then save that to a file (I assume that's what you're doing)

// Get it back will look like: 
var back_from_json = Newtonsoft.Json.JsonConvert
                                    .DeserializeObject<your_poco_class>(json);

// and then simply use the object's lists:
var dates  = back_from_json.event_dates_list; // list of dates
var events = = back_from_json.events;         // list of events? 

你的 poco 只是用于事件日期。
你需要另一个带有变量的 poco 来处理其余部分:

"document", "result", "resultcode", "note", "totaldates", "date"

它可能会被称为 documenttotaldates 将是一个 int,而 date 将是一个 List<DateEvent>
这就是你将要序列化和反序列化的内容。


谢谢你的回答。我编辑了我的帖子,请再次查看它。 - Vitach
负评者...原因? - Noctis

-2
首先,在您的类中将RootObject类的实例转换为列表,例如:
class RootObject
{
public List<Class1> Property1 { get; set; }
}

现在你可以像列表一样访问该类中的项目。

1
你没有理解问题的关键点——有时属性是一个数组,有时它是一个单独的对象。如果你将其声明为列表,在JSON只有一个对象时它将无法工作,反之亦然。解决方案不仅仅是改变类的声明(尽管这是其中的一部分)。 - Brian Rogers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接