C# 当我没有';不知道密钥和属性不';你没有名字吗?

C# 当我没有';不知道密钥和属性不';你没有名字吗?,c#,json,json.net,C#,Json,Json.net,以下是我的未解析JSON: {“1”:[[2015,6,1,8,0,0,3600,“欧洲/伦敦”,“英国标准时间”,1][ 2015,6,1,9,30,0,3600,“欧洲/伦敦”,“英国夏令时”,1],[[2015, 6,1,8,30,03600,“欧洲/伦敦”,“英国夏令时”,1],[2015,6,1,10, 0,0,3600,“欧洲/伦敦”,“英国夏令时”,1],[[2015,6,1,9,0,0, 3600,“欧洲/伦敦”,“英国夏令时”,1),[2015,6,1,10,30,03600,

以下是我的未解析JSON:

{“1”:[[2015,6,1,8,0,0,3600,“欧洲/伦敦”,“英国标准时间”,1][ 2015,6,1,9,30,0,3600,“欧洲/伦敦”,“英国夏令时”,1],[[2015, 6,1,8,30,03600,“欧洲/伦敦”,“英国夏令时”,1],[2015,6,1,10, 0,0,3600,“欧洲/伦敦”,“英国夏令时”,1],[[2015,6,1,9,0,0, 3600,“欧洲/伦敦”,“英国夏令时”,1),[2015,6,1,10,30,03600, “欧洲/伦敦”、“英国标准时间”,1]],[[2015,6,1,9,30,0,3600, 《欧洲/伦敦》,《英国夏令时》第1期,[2015年第6期、第1期、第11期、第0期、第0期、第3600期、, “欧洲/伦敦”、“英国标准时间”,1]]],“2”:[[2015,6,2,8,0,0,3600, 《欧洲/伦敦》,《英国夏令时》第1期,[2015年第6、2、9、30、0、3600页, “欧洲/伦敦”、“英国标准时间”,1]],[[2015,6,2,8,30,0,3600, 《欧洲/伦敦》,《英国标准时间》,1),[2015,6,2,10,0,0,3600, “欧洲/伦敦”、“英国标准时间”,1]],[[2015,6,2,9,0,0,3600, 《欧洲/伦敦》,《英国标准时间》,1),[2015,6,2,10,30,0,3600, “欧洲/伦敦”、“英国标准时间”,1]],[[2015,6,2,9,30,0,3600, 《欧洲/伦敦》,《英国标准时间》,1),[2015,6,2,11,0,0,3600, “欧洲/伦敦”、“英国标准时间”,1]]],“3”:[[2015,6,3,8,0,0,3600, 《欧洲/伦敦》,《英国夏令时》第1期,[2015年第6、3、9、30、0、3600页, “欧洲/伦敦”、“英国标准时间”,1]],[[2015,6,3,8,30,0,3600, 《欧洲/伦敦》,《英国标准时间》,第1页,[2015年,第6、3、10、0、0、3600页, “欧洲/伦敦”、“英国标准时间”,1]],[[2015,6,3,9,0,0,3600, 《欧洲/伦敦》,《英国夏令时》第1期,[2015年第6、3、10、30、0、3600页, “欧洲/伦敦”、“英国标准时间”,1]],[[2015,6,3,9,30,0,3600, 《欧洲/伦敦》,《英国标准时间》,第1页,[2015年,第6、3、11、0、0、3600页, “欧洲/伦敦”、“英国标准时间”,1]]],“4”:[[2015,6,4,8,0,0,3600, 《欧洲/伦敦》,《英国标准时间》,1),[2015年6月、4日、9日、30日、0日、3600日、, “欧洲/伦敦”、“英国标准时间”,1]],[[2015,6,4,8,30,0,3600, 《欧洲/伦敦》,《英国标准时间》,1),[2015,6,4,10,0,0,3600, “欧洲/伦敦”、“英国标准时间”,1]],[[2015,6,4,9,0,0,3600, 《欧洲/伦敦》,《英国夏令时》第1期,[2015年第6、4、10、30、0、3600页, “欧洲/伦敦”、“英国标准时间”,1]],[[2015,6,4,9,30,0,3600, 《欧洲/伦敦》,《英国标准时间》,第1页,[2015年,第6、4、11、0、0、3600页, “欧洲/伦敦”、“英国夏令时”,1]]]}

这是基本格式:

这就是它的格式:

我一辈子都想不出怎么钻过去。这个问题应该类似于

如果执行以下操作,我会得到“System.invalidoOperationException:无法访问Newtonsoft.Json.Linq.JValue上的子值。”


您可以做的是设计一个类(命名为,例如,
Entry
)来表示JSON中表示最低级别数组的数据:
[2015,6,3,9,30,0,3600,“欧洲/伦敦”,“BST”,1]
。然后创建一个数组,将数组值按顺序加载到数组中。最后,根据需要反序列化外部字典和数组:

下面是一个可能的类来表示单个内部数组的数据:

[JsonConverter(typeof(EntryConverter))]
public class Entry
{
    public Entry()
    {
        // You need to determine whether the time numbers in the JSON are in UTC or in the timezone given in the "TimeZone" field.  If
        // Local, change to DateTimeKind.Local
        DateTime = new DateTime(0, DateTimeKind.Utc); 
    }

    public DateTime DateTime { get; set; }
    public int Number { get; set; } // That 3600 thing.  No idea what it's for.
    public string Destination { get; set; }
    public string TimeZone { get; set; }
    // Not all time zone offsets are integers: https://en.wikipedia.org/wiki/UTC%E2%88%9204:30
    public decimal GmtOffset { get; set; }
}
接下来,转换器:

public class EntryConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(Entry).IsAssignableFrom(objectType);
    }

    void SetField(Entry entry, int index, JValue value)
    {
        switch (index)
        {
            case 0:
                entry.DateTime = new DateTime((int)value, entry.DateTime.Month, entry.DateTime.Day, entry.DateTime.Hour, entry.DateTime.Minute, entry.DateTime.Second, entry.DateTime.Millisecond, entry.DateTime.Kind);
                break;
            case 1:
                entry.DateTime = new DateTime(entry.DateTime.Year, (int)value, entry.DateTime.Day, entry.DateTime.Hour, entry.DateTime.Minute, entry.DateTime.Second, entry.DateTime.Millisecond, entry.DateTime.Kind);
                break;
            case 2:
                entry.DateTime = new DateTime(entry.DateTime.Year, entry.DateTime.Month, (int)value, entry.DateTime.Hour, entry.DateTime.Minute, entry.DateTime.Second, entry.DateTime.Millisecond, entry.DateTime.Kind);
                break;
            case 3:
                entry.DateTime = new DateTime(entry.DateTime.Year, entry.DateTime.Month, entry.DateTime.Day, (int)value, entry.DateTime.Minute, entry.DateTime.Second, entry.DateTime.Millisecond, entry.DateTime.Kind);
                break;
            case 4:
                entry.DateTime = new DateTime(entry.DateTime.Year, entry.DateTime.Month, entry.DateTime.Day, entry.DateTime.Hour, (int)value, entry.DateTime.Second, entry.DateTime.Millisecond, entry.DateTime.Kind);
                break;
            case 5:
                entry.DateTime = new DateTime(entry.DateTime.Year, entry.DateTime.Month, entry.DateTime.Day, entry.DateTime.Hour, entry.DateTime.Minute, (int)value, entry.DateTime.Millisecond, entry.DateTime.Kind);
                break;
            case 6:
                entry.Number = (int)value;
                break;
            case 7:
                entry.Destination = (string)value;
                break;
            case 8:
                entry.TimeZone = (string)value;
                break; 
            case 9:
                entry.GmtOffset = (decimal)value;
                break;
            default:
                throw new IndexOutOfRangeException(index.ToString());
        }
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var array = JArray.Load(reader);
        if (array == null)
            return existingValue;
        var entry = (existingValue as Entry ?? new Entry());
        for (int i = 0; i < array.Count; i++)
        {
            SetField(entry, i, (JValue)array[i]);
        }
        return entry;
    }

    public override bool CanWrite { get { return false; } }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}
公共类入口转换器:JsonConverter
{
公共覆盖布尔CanConvert(类型objectType)
{
返回类型(条目)。IsAssignableFrom(对象类型);
}
void设置字段(条目、整数索引、JValue)
{
开关(索引)
{
案例0:
entry.DateTime=new DateTime((int)值,entry.DateTime.Month,entry.DateTime.Day,entry.DateTime.Hour,entry.DateTime.Minute,entry.DateTime.Second,entry.DateTime.millis秒,entry.DateTime.Kind);
打破
案例1:
entry.DateTime=new DateTime(entry.DateTime.Year,(int)值,entry.DateTime.Day,entry.DateTime.Hour,entry.DateTime.Minute,entry.DateTime.Second,entry.DateTime.millis秒,entry.DateTime.Kind);
打破
案例2:
entry.DateTime=new DateTime(entry.DateTime.Year,entry.DateTime.Month,(int)值,entry.DateTime.Hour,entry.DateTime.Minute,entry.DateTime.Second,entry.DateTime.Millisecond,entry.DateTime.Kind);
打破
案例3:
entry.DateTime=new DateTime(entry.DateTime.Year,entry.DateTime.Month,entry.DateTime.Day,(int)值,entry.DateTime.Minute,entry.DateTime.Second,entry.DateTime.millisond,entry.DateTime.Kind);
打破
案例4:
entry.DateTime=new DateTime(entry.DateTime.Year,entry.DateTime.Month,entry.DateTime.Day,entry.DateTime.Hour,(int)值,entry.DateTime.Second,entry.DateTime.millis秒,entry.DateTime.Kind);
打破
案例5:
entry.DateTime=new DateTime(entry.DateTime.Year,entry.DateTime.Month,entry.DateTime.Day,entry.DateTime.Hour,entry.DateTime.Minute,(int)值,entry.DateTime.毫秒,entry.DateTime.Kind);
打破
案例6:
entry.Number=(int)值;
打破
案例7:
entry.Destination=(字符串)值;
打破
案例8:
entry.TimeZone=(字符串)值;
打破
案例9:
entry.GmtOffset=(十进制)值;
打破
违约:
抛出新的IndexOutOfRangeException(index.ToString());
}
}
公共重写对象ReadJson(JsonReader阅读器,类型objectType,对象existingValue,JsonSerializer序列化程序)
{
var数组=JArray.Load(读卡器);
if(数组==null)
返回现有值;
var entry=(existingValue作为条目??new entry());
for(int i=0;i
然后像这样使用它:

        var root = JsonConvert.DeserializeObject<Dictionary<int, List<List<Entry>>>>(json);
        Debug.WriteLine(JsonConvert.SerializeObject(root, Formatting.Indented));
va
public class EntryConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(Entry).IsAssignableFrom(objectType);
    }

    void SetField(Entry entry, int index, JValue value)
    {
        switch (index)
        {
            case 0:
                entry.DateTime = new DateTime((int)value, entry.DateTime.Month, entry.DateTime.Day, entry.DateTime.Hour, entry.DateTime.Minute, entry.DateTime.Second, entry.DateTime.Millisecond, entry.DateTime.Kind);
                break;
            case 1:
                entry.DateTime = new DateTime(entry.DateTime.Year, (int)value, entry.DateTime.Day, entry.DateTime.Hour, entry.DateTime.Minute, entry.DateTime.Second, entry.DateTime.Millisecond, entry.DateTime.Kind);
                break;
            case 2:
                entry.DateTime = new DateTime(entry.DateTime.Year, entry.DateTime.Month, (int)value, entry.DateTime.Hour, entry.DateTime.Minute, entry.DateTime.Second, entry.DateTime.Millisecond, entry.DateTime.Kind);
                break;
            case 3:
                entry.DateTime = new DateTime(entry.DateTime.Year, entry.DateTime.Month, entry.DateTime.Day, (int)value, entry.DateTime.Minute, entry.DateTime.Second, entry.DateTime.Millisecond, entry.DateTime.Kind);
                break;
            case 4:
                entry.DateTime = new DateTime(entry.DateTime.Year, entry.DateTime.Month, entry.DateTime.Day, entry.DateTime.Hour, (int)value, entry.DateTime.Second, entry.DateTime.Millisecond, entry.DateTime.Kind);
                break;
            case 5:
                entry.DateTime = new DateTime(entry.DateTime.Year, entry.DateTime.Month, entry.DateTime.Day, entry.DateTime.Hour, entry.DateTime.Minute, (int)value, entry.DateTime.Millisecond, entry.DateTime.Kind);
                break;
            case 6:
                entry.Number = (int)value;
                break;
            case 7:
                entry.Destination = (string)value;
                break;
            case 8:
                entry.TimeZone = (string)value;
                break; 
            case 9:
                entry.GmtOffset = (decimal)value;
                break;
            default:
                throw new IndexOutOfRangeException(index.ToString());
        }
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var array = JArray.Load(reader);
        if (array == null)
            return existingValue;
        var entry = (existingValue as Entry ?? new Entry());
        for (int i = 0; i < array.Count; i++)
        {
            SetField(entry, i, (JValue)array[i]);
        }
        return entry;
    }

    public override bool CanWrite { get { return false; } }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}
        var root = JsonConvert.DeserializeObject<Dictionary<int, List<List<Entry>>>>(json);
        Debug.WriteLine(JsonConvert.SerializeObject(root, Formatting.Indented));
public class TimeSlotInfo
{
    public int DayOfMonth { get; set; }

    public List<TimeSlotRange> TimeSlots { get; set; }

    public TimeSlotInfo()
    {
        TimeSlots = new List<TimeSlotRange>();
    }
}

public class TimeSlotRange
{
    public TimeSlotItem Start { get; set; }

    public TimeSlotItem End { get; set; }
}

public class TimeSlotItem
{
    public int Year { get; set; }

    public int Month { get; set; }

    public int Day { get; set; }

    public int Hour { get; set; }

    public int Minute { get; set; }

    public int Second { get; set; }

    public int SecondsInHour { get; set; }

    public string TimezoneStr { get; set; }

    public string BST { get; set; }

    public int SomeNum { get; set; }

    public DateTime AsDateTime
    {
        get { return new DateTime(Year, Month, Day, Hour, Minute, Second); }
    }

    public static TimeSlotItem CreateFromJTokenList(List<JToken> tokenList)
    {
        try
        {
            var result = new TimeSlotItem
            {
                Year = tokenList[0].Value<int>(),
                Month = tokenList[1].Value<int>(),
                Day = tokenList[2].Value<int>(),
                Hour = tokenList[3].Value<int>(),
                Minute = tokenList[4].Value<int>(),
                Second = tokenList[5].Value<int>(),
                SecondsInHour = tokenList[6].Value<int>(),
                TimezoneStr = tokenList[7].Value<string>(),
                BST = tokenList[8].Value<string>(),
                SomeNum = tokenList[9].Value<int>()
            };

            return result;
        }
        catch (Exception)
        {
            return null;
        }
    }
}
var timeSlotInfoList = new List<TimeSlotInfo>();

var jsonVal = System.IO.File.ReadAllText(@"C:\test.json"); // Somehow get JSON string into jsonVal. Not neccessarily from file.
var obj = JsonConvert.DeserializeObject(jsonVal) as JObject;
if (obj != null)
{
    var jobj = obj.AsQueryable();
    foreach (JProperty item in jobj)
    {
        try
        {
            var dayOfMonth = Convert.ToInt32(item.Name);

            var timeSlotInfo = new TimeSlotInfo
            {
                DayOfMonth = dayOfMonth
            };
            timeSlotInfoList.Add(timeSlotInfo);

            var timeSlots = item.Value.ToList();
            foreach (var timeSlotPair in timeSlots)
            {
                var timeSlotPairList = timeSlotPair.ToList();
                if (timeSlotPairList.Count != 2)
                    continue;

                var slotItemStart = TimeSlotItem.CreateFromJTokenList(timeSlotPairList[0].ToList());
                var slotItemEnd = TimeSlotItem.CreateFromJTokenList(timeSlotPairList[0].ToList());

                if (slotItemStart != null && slotItemEnd != null)
                {
                    timeSlotInfo.TimeSlots.Add(new TimeSlotRange
                    {
                        Start = slotItemStart,
                        End = slotItemEnd,
                    });
                }
            }

        }
        catch (Exception)
        {
        }
    }
}