JSON.NET不会在Unity中协调冒号

时间:2019-12-24 15:34:37

标签: c# json unity3d json.net

在我的项目中测试并调试了一个级别生成器后,我从Unity3d中使用JSON.Net发生了一个奇怪的错误,该级别生成器从资源中读取文件并将文件写入桌面。生成器读取json文件的特定部分,这可以正常工作。在从统一编辑器崩溃时,同时对数据进行序列化和反序列化以及对旧数据进行异步处理。

由于崩溃,Json.Net在反序列化文件的一部分时给出错误。看起来Json.Net不再识别冒号了。我收到以下错误:

JsonSerializationException: Unexpected token while deserializing object: PropertyName. Path 'Levels', line 2, position 12.
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, System.Object existingValue) (at <97722d3abc9f4cf69f9e21e6770081b3>:0)
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Boolean checkAdditionalContent) (at <97722d3abc9f4cf69f9e21e6770081b3>:0)
Newtonsoft.Json.JsonSerializer.DeserializeInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType) (at <97722d3abc9f4cf69f9e21e6770081b3>:0)
Newtonsoft.Json.JsonSerializer.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType) (at <97722d3abc9f4cf69f9e21e6770081b3>:0)
Newtonsoft.Json.Linq.JToken.ToObject (System.Type objectType, Newtonsoft.Json.JsonSerializer jsonSerializer) (at <97722d3abc9f4cf69f9e21e6770081b3>:0)
Newtonsoft.Json.Linq.JToken.ToObject (System.Type objectType) (at <97722d3abc9f4cf69f9e21e6770081b3>:0)
Newtonsoft.Json.Linq.JToken.ToObject[T] () (at <97722d3abc9f4cf69f9e21e6770081b3>:0)
JsonHelper+<GetCollection>d__3`1[T].MoveNext () (at Assets/Scripts/Utils/JsonHelper.cs:25)
{
   "Levels":[

   ],
   "DefaultConfig":{
      "FieldSize":{
         "Height":25,
         "Width":27
      },
      "FieldBlocks":{
         "BlockScale":3,
         "CenterTop":10,
         "FieldTop":9
      }
   }
}
using System.Threading.Tasks;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;

using System;

public static class JsonHelper
{
    private static JObject jsonRoot;

    public static void InitializeJsonHelper(string json)
    {
        jsonRoot = JObject.Parse(json);
    }

    public static async Task<T> GetObjectFromJson<T>(string section)
    {
        JToken token = await FindTokenWithSectionName(section);
        return token.ToObject<T>();
    }

    public static async Task<List<T>> GetCollection<T>(string section)
    {
        JToken token = await FindTokenWithSectionName(section);
        return token.ToObject<List<T>>();
    }

    public static async Task<string> AddCollectionToSection<T>(ICollection<T> objects, string section)
    {
        try
        {
            JProperty currentProperty = await FindTokenWithSectionName(section);
            JProperty newProperty = new JProperty(currentProperty);

            /*var objectsAsJson = JsonConvert.SerializeObject(objects);

            newProperty.Value = JToken.Parse(objectsAsJson);*/
            currentProperty.Replace(newProperty);

            await SetReplaceTokenToSection(currentProperty, section);
            return jsonRoot.ToString();
        }
        catch (Exception exception)
        {
            return exception.StackTrace;
        }
    }
    public static async Task<string>AddObjectToSection<T>(T newObject, string section)
    {
        JToken token = await FindTokenWithSectionName(section);
        JValue valueOfToken = new JValue(newObject);
        token.Replace(valueOfToken);

        await SetReplaceTokenToSection(token, section);
        return jsonRoot.ToString();
    }

    private static async Task<JProperty> FindTokenWithSectionName(string section)
    {
        return await Task.Run(() =>
         {
             JProperty property = jsonRoot.Property(section);
             return property;
         });
    }

    private static Task SetReplaceTokenToSection(JToken newToken, string section)
    {
        JProperty property = jsonRoot.Property(section);
        property.Value = newToken;

        return Task.CompletedTask;
    }
}

如何解决错误?

1 个答案:

答案 0 :(得分:2)

您的问题是您正在尝试将JProperty反序列化为某些内容。相反,您需要反序列化其value

public static async Task<T> GetObjectFromJson<T>(string section)
{
    JProperty token = await FindTokenWithSectionName(section);
    return token.Value.ToObject<T>(); // What to do if token is null?
}

public static async Task<List<T>> GetCollection<T>(string section)
{
    JProperty token = await FindTokenWithSectionName(section);
    return token.Value.ToObject<List<T>>(); // What to do if token is null?
}

JProperty代表JObject中的命名值;您想反序列化值本身。

偶然地,我没有看到使FindTokenWithSectionName()异步运行的理由。 JToken层次结构是某些JSON的内存表示形式,因此将不执行I / O,而JObject.Property(string name)只是dictionary lookup,因此应该很快。而且,如果JsonHelper是诸如数据库查找之类的慢速对象的模型,那么我就不会期望该类是静态的,因为静态类不适合用于依赖项注入。

此外,在静态类中使用静态字段来捕获某些运行时加载的JSON看起来可能是线程不安全的。

演示小提琴here