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

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的问题 以及反序列化的问题

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Unity 中,我们可以使用 JsonUtility 类来实现对象的序列化和反序列化。对于 Dictionary 类型的对象,我们可以通过将其转换为一个包含键对的 List 类型对象,然后对 List 类型对象进行序列化和反序列化。 下面是一个示例代码: ```csharp using System.Collections.Generic; using UnityEngine; [System.Serializable] public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, ISerializationCallbackReceiver { [SerializeField] private List<TKey> keys = new List<TKey>(); [SerializeField] private List<TValue> values = new List<TValue>(); // save the dictionary to lists public void OnBeforeSerialize() { keys.Clear(); values.Clear(); foreach (KeyValuePair<TKey, TValue> pair in this) { keys.Add(pair.Key); values.Add(pair.Value); } } // load dictionary from lists public void OnAfterDeserialize() { this.Clear(); for (int i = 0; i < keys.Count; i++) { this.Add(keys[i], values[i]); } } } [System.Serializable] public class MyData { public SerializableDictionary<string, int> myDict = new SerializableDictionary<string, int>(); } public static class JsonHelper { public static string ToJson<T>(T obj) { return JsonUtility.ToJson(obj); } public static T FromJson<T>(string json) { return JsonUtility.FromJson<T>(json); } } public class Example : MonoBehaviour { private MyData data = new MyData(); private void Start() { data.myDict.Add("key1", 1); data.myDict.Add("key2", 2); string json = JsonHelper.ToJson(data); Debug.Log(json); MyData loadedData = JsonHelper.FromJson<MyData>(json); Debug.Log(loadedData.myDict["key1"]); Debug.Log(loadedData.myDict["key2"]); } } ``` 在上面的示例代码中,我们定义了一个 SerializableDictionary 类来实现 Dictionary 的序列化和反序列化。在 MyData 类中使用了 SerializableDictionary 类型的成员变量 myDict。在 JsonHelper 类中,我们定义了 ToJson 和 FromJson 方法来将对象转换为 Json 字符串和从 Json 字符串中加载对象。在 Example 类中,我们创建了一个 MyData 对象,并向其中添加了两个键对。我们将 MyData 对象转换为 Json 字符串并输出到控制台,然后从 Json 字符串中加载了一个新的对象,并输出了其中的两个

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

染指流年丨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值