0

我有以下 json 字符串:

    {"Visits":[true,"DockedOnly","leftZone","0","500",0,0,0],
     "Weather":[true,"DockedOnly","leftZone","0","0",0,0,1],
     "ContactUs":[true,"DockedOnly","leftZone","0","317",0,0,2],
     "Birthdays":[true,"DockedOnly","middleZone","0","0",0,0,0],
     "Reminders":[true,"DockedOnly","middleZone","0","145",0,0,1],
     "Messages":[true,"DockedOnly","middleZone","0","0",0,0,2],
     "Availability":[true,"DockedOnly","middleZone","0","0",0,0,3],
     "Settings":[false,"DockedOnly","leftzone","0","155",0,0,0]}

无论如何要反序列化为以下内容?

    [Serializable]
    public class WidgetProps
    {
        public bool Visible { get; set; }
        public string DockState { get; set; }
        public string Zone { get; set; }
        public string Top { get; set; }
        public string Left { get; set; }
        public int UnusedA { get; set; }
        public int UnusedB { get; set; }
        public int Position { get; set; }
    }

    [Serializable]
    public class WidgetLayout
    {
        public WidgetProps Visits { get; set; }
        public WidgetProps Weather { get; set; }
        public WidgetProps ContactUs { get; set; }
        public WidgetProps Birthdays { get; set; }
        public WidgetProps Reminders { get; set; }
        public WidgetProps Messages { get; set; }
        public WidgetProps Availability { get; set; }
        public WidgetProps Settings { get; set; }
    }

或者

    public class Widget
    {
        public string WidgetName { get; set; }
        public WidgetProps props { get; set; }
    }

    List<Widget> MyWidgets;

我得到了 json 字符串,所以我不能改变它是如何给我的,但也许我可以在得到它之后修改它,这样它就可以工作了。

我试过了:

    string s = "{\"Visits\":[true,\"DockedOnly\",\"leftZone\",\"0\",\"500\",0,0,0],\"Weather\":[true,\"DockedOnly\",\"leftZone\",\"0\",\"0\",0,0,1],\"ContactUs\":[true,\"DockedOnly\",\"leftZone\",\"0\",\"317\",0,0,2],\"Birthdays\":[true,\"DockedOnly\",\"middleZone\",\"0\",\"0\",0,0,0],\"Reminders\":[true,\"DockedOnly\",\"middleZone\",\"0\",\"145\",0,0,1],\"Messages\":[true,\"DockedOnly\",\"middleZone\",\"0\",\"0\",0,0,2],\"Availability\":[true,\"DockedOnly\",\"middleZone\",\"0\",\"0\",0,0,3],\"Settings\":[false,\"DockedOnly\",\"leftzone\",\"0\",\"155\",0,0,0]}}";
    var sd = new JavaScriptSerializer().Deserialize < List<Widget>>(s);

    var sd = new JavaScriptSerializer().Deserialize < WidgetLayout >(s);
4

2 回答 2

0

这不起作用,因为您试图将数组反序列化为对象。json.NET 反序列化器将无法进行该转换。

因为您的 json 数组中有多种类型,所以您必须反序列化为最小的公分母,在这种情况下,object. 从那里我建议编写一个方法来将每个索引分配给它在 WidgetProps 中的相应属性。

所以基本上,定义这个构造函数;

public WidgetProps(object[] props)
{
    Visible = (bool)props[0];
    DockState = (string)props[1];
    // ext
}

我会有一个类似于WidgetDirty我进行初始反序列化的类的东西。从那里你可以WidgetLayout通过实例化它的每个属性来创建一个新实例,就像myWidgetLayoutInstance.Visits = new WidgetProp(myWidgetDirtyInstance.Visits);我可能会将这个混乱隐藏在一个WidgetLayout构造函数中,WidgetDirty因为它只是一个 arg。

是的,这很恶心......但我不知道任何真正的替代品,因为 json 的设计与 C# 语言不太兼容。如果您对此强烈反对,我可能会查看dynamic类型。我没有在 C# 中使用过它,可能永远也不会,但我知道用 PHP 这样的动态语言反序列化它一点也不麻烦。

于 2013-06-13T23:22:03.870 回答
0

这不起作用,因为数组通常不会反序列化为对象。如果可能的话,我认为你应该修复 JSON。如果你不能这样做,并且你正在使用 JSON.NET,你可以创建手动将数组转换为对象JsonConverterWidgetProps

class WidgetPropsConverter : JsonConverter
{
    public override void WriteJson(
        JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotSupportedException();
    }

    public override object ReadJson(
        JsonReader reader, Type objectType, object existingValue,
        JsonSerializer serializer)
    {
        var array = serializer.Deserialize<object[]>(reader);
        return new WidgetProps
        {
            Visible = (bool)array[0],
            DockState = (string)array[1],
            Zone = (string)array[2],
            Top = (string)array[3],
            Left = (string)array[4],
            Position = (int)(long)array[7]
        };
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(WidgetProps);
    }
}

然后你会像这样使用它:

var result = JsonConvert.DeserializeObject<WidgetLayout>(
    jsonString, new WidgetPropsConverter());
于 2013-06-14T00:07:13.910 回答