如何反序列化这个json字符串到类

本文关键字:字符串 json 反序列化 | 更新日期: 2023-09-27 18:18:32

我有以下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);

如何反序列化这个json字符串到类

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

因为你的json数组有多种类型,你必须反序列化成最小的公分母,在这种情况下,object。从那里,我建议写一个方法来分配每个索引对应的属性在WidgetProps。

也就是定义这个构造函数;
public WidgetProps(object[] props)
{
    Visible = (bool)props[0];
    DockState = (string)props[1];
    // ext
}

我将有一个类似WidgetDirty类的东西,我将初始反序列化到其中。从那里,你可以通过实例化myWidgetLayoutInstance.Visits = new WidgetProp(myWidgetDirtyInstance.Visits);的每个属性来创建WidgetLayout的新实例,我可能会将这个混乱隐藏在WidgetLayout构造函数中,该构造函数接受WidgetDirty作为唯一的参数。

是的,它很恶心…但我不知道有什么真正的替代方案,因为json的设计与c#语言不是很兼容。如果你强烈反对这一点,我可能会考虑dynamic类型。我还没有在c#中使用它,可能永远也不会,但我知道在像PHP这样的动态语言中反序列化它一点也不麻烦。

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

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());