Unity NewtonSoft插件 反序列化json报错 Unable to find a constructor 以及 反序列化出来的对象没有值的问题

使用NewtonSoft插件,用插件里面的Deserialize方法进行json的反序列化,unity导出的程序在WebGL正常运行,但是在安卓出现报错Unable to find a constructor,按照 网上的说法将每个要解析的类添加一个空构造函数,然后试了好像还是不行,然后搜了一会,再给其中一个空构造函数上面添加[Preserve]属性,这个属性是UnityEngine里面的UnityEngine.Scripting命名空间里面的,然后打包之后就可以正常反序列化了,猜测对一个空构造方法方法加了这个属性之后 所有的空构造方法都会保留 如果一个空构造方法都没加这个属性 就会报错。

但是在ios端,要求比安卓会更加严格一点,单纯按照安卓的做法去做的话,能进行json反序列化成对象但是反序列化出来的对象里面的值都是默认值,这个的解决方案是每个反序列化的类定义的时候都要再添加一个带参构造函数,需要反序列化的值都在构造函数的形参里面写好,然后在构造函数内将形参与对象变量进行一一赋值,在这个带参构造函数的定义上一行也需要添加[Preserve]属性,然后还有一点是在ios开发环境中oc的id是个关键字,如果传过来的json里面有个字段的key值是id,在解析之前将小写的id替换称为大写的ID,在定义的反序列化的类里面将id对应的属性改成ID。
每个定义的对象里面不仅需要由[Preserve]声明修饰的带参构造函数,还需要由[Preserve]声明修饰的空构造函数,不然在安卓的反序列化会出错
最后定义好的能在ios进行Newtonsoft Deseriialize进行解析的类如下所示

public class HallShopData
{
    public string unitId { get; set; }

    public int type { get; set; }

    public string imgUrl { get; set; }

    public string name { get; set; }

    public string signImgUrl { get; set; }
    public string signImgOffsetX { get; set; }
    public string signImgOffsetY { get; set; }
    public string signImgTilingX { get; set; }
    public string signImgTilingY { get; set; }
    public string videoCover { get; set; }
    public string videoUrl { get; set; }

    public List<SingleItemData> unitItemList { get; set; }

    public List<SingleProductData> unitProductList { get; set; }

    public HallShopRelativeData unitInfo { get; set; }


    [Preserve]
    public HallShopData()
    {

    }

    [Preserve]
    public HallShopData(string unitId, int type, string imgUrl,
        string name, string signImgUrl, string signImgOffsetX,
        string signImgOffsetY, string signImgTilingX, string signImgTilingY,
        string videoCover, string videoUrl, List<SingleItemData> unitItemList,
         List<SingleProductData> unitProductList, HallShopRelativeData unitInfo)
    {
        this.unitId = unitId;
        this.type = type;
        this.imgUrl = imgUrl;
        this.name = name;
        this.signImgUrl = signImgUrl;
        this.signImgOffsetX = signImgOffsetX;
        this.signImgOffsetY = signImgOffsetY;
        this.signImgTilingX = signImgTilingX;
        this.signImgTilingY = signImgTilingY;
        this.videoCover = videoCover;
        this.videoUrl = videoUrl;
        this.unitItemList = unitItemList;
        this.unitProductList = unitProductList;
        this.unitInfo = unitInfo;

    }

    public virtual string GetPlaceID()
    {
        if (unitInfo != null && unitInfo.unitTag != null &&
            unitInfo.unitTag != string.Empty)
        {
            return unitInfo.unitTag;
        }

        Debug.LogError(" HallShopServerLoadAndInitData GetPlaceID return -1 ");
        return Const.negativeOneStr;
    }
}

如果json要解析出来的类是继承了另外一个解析类的话, 可以这样写:


public class PermanentHallShopData : HallShopData
{
    public int ID { get; set; }

    public override string GetPlaceID()
    {
        if (ID > Const.zeroInt)
        {
            //要从"1"这样的字符串转换为"001"这样的
            return ID.ToString("000");
        }

        Debug.LogError(" HallShopServerLoadAndInitData GetPlaceID return -1 " +
            "because id is invalid, id value  " + ID);
        return Const.negativeOneStr;
    }

    [Preserve]
    public PermanentHallShopData(int id, string unitId, int type, string imgUrl,
        string name, string signImgUrl, string signImgOffsetX,
        string signImgOffsetY, string signImgTilingX, string signImgTilingY,
        string videoCover, string videoUrl, List<SingleItemData> unitItemList,
         List<SingleProductData> unitProductList,
        HallShopRelativeData unitInfo) : base(unitId, type, imgUrl,
         name, signImgUrl, signImgOffsetX,
         signImgOffsetY, signImgTilingX, signImgTilingY,
         videoCover, videoUrl, unitItemList,
         unitProductList, unitInfo)
    {
        this.ID = id;
    }

    [Preserve]
    public PermanentHallShopData()
    {

    }

}

PermanentHallShopData 继承自HallShopData这个类,这样写可以保证 Newtonsoft在ios进行反序列化的时候PermanentHallShopData类型的对象能生成


如果要解析的类有嵌套的话也是可以的

public class ExhibitionSeatInfo
{
    public int pageNum { get; set; }
    public int pageSize { get; set; }
    public int totalPage { get; set; }
    public int total { get; set; }

    public List<ExhibitionPerSeatInfo> rows { get; set; }

    [Preserve]
    public ExhibitionSeatInfo()
    {

    }

    [Preserve]
    public ExhibitionSeatInfo(int pageNum, int pageSize,
        int totalPage, int total,
       List<ExhibitionPerSeatInfo> rows)
    {
        this.pageNum = pageNum;
        this.pageSize = pageSize;
        this.totalPage = totalPage;
        this.total = total;
        this.rows = rows;
    }
}
public class ExhibitionPerSeatInfo
{
    public int area { get; set; }
    public string areaTag { get; set; }
    public string categoryId { get; set; }
    public string categoryName { get; set; }
    public string categoryNameUs { get; set; }
    public int collectNum { get; set; }
    public string exhibitionId { get; set; }
    public string hallTag { get; set; }
    public int hotNum { get; set; }

    [JsonProperty(PropertyName = "id")]
    public string ID { get; set; }

    public string logicTag { get; set; }
    public string putSellerId { get; set; }
    public int roomType { get; set; }
    public string turnover { get; set; }
    public string unitTag { get; set; }

    public override string ToString()
    {
        string str = "ExhibitionPerSeatInfo ID " + ID;
        return str;
    }

    [Preserve]
    public ExhibitionPerSeatInfo()
    {

    }


    [Preserve]
    public ExhibitionPerSeatInfo(int area, string areaTag, string categoryId,
        string categoryName, string categoryNameUs, int collectNum,
         string exhibitionId, string hallTag, int hotNum,
          string id, string logicTag, string putSellerId,
           int roomType, string turnover, string unitTag )
    {
        this.area = area;
        this.areaTag = areaTag;
        this.categoryId = categoryId;
        this.categoryName = categoryName;
        this.categoryNameUs = categoryNameUs;
        this.collectNum = collectNum;
        this.exhibitionId = exhibitionId;
        this.hallTag = hallTag;
        this.hotNum = hotNum;
        this.ID = id;
        this.logicTag = logicTag;
        this.putSellerId = putSellerId;
        this.roomType = roomType;
        this.turnover = turnover;
        this.unitTag = unitTag;

    }
}

Json解析类ExhibitionPerSeatInfo里面有个变量rows是另外一个解析类ExhibitionPerSeatInfo,只要这两个解析类都按照规范写,在ios上面的解析就没有问题,注意构造函数里面某个要解析的字段不要写漏了,写漏了,ios解析的话这个值是空的

这种方法可能会显得有点繁琐,可以尝试下文中,去掉getset声明的方法
Unity Newtonsoft插件在ios无法序列化出json的问题 以及反序列化的问题

你可能感兴趣的:(Unity NewtonSoft插件 反序列化json报错 Unable to find a constructor 以及 反序列化出来的对象没有值的问题)