JsonConvert:转换为另一种类型只能在顶层工作

时间:2018-06-08 09:36:35

标签: c# json unity3d json.net

编辑:事实证明它并没有与关卡相关联。它在一个班级中工作得很好,但在其他班级却没有,我还没有弄清楚为什么还是有时间进一步调查它。

我已经采取了一些琐事。 hacky但非常方便能够在我的JSON中执行此操作:

"Folder": "path/to/folder"
// or
"Folder": {"Path": "path/to/folder", "ExtraInfo": "..."}

它们不是同一类型,但我的Folder类包含这个:

static public explicit operator Folder(string path)
{
    return new Folder(path);
}

然后我用ScriptableObject填充:

Data = ScriptableObject.CreateInstance<T>();
JsonConvert.PopulateObject(json, Data);

一切正常,直到它进一步嵌套到我的JSON中,我想以这种方式使用Folder

{
    "ComplexData" : [
        {
            "Folders" : [
                 "path/to/A", // Where the magic (the casting) should also happen but doesn't
                 "path/to/B" // Same here
             ]
        },
        { // Error raises here
            "Folders" : []
        }
     ]
}

ComplexDataFolderPack

的公开列表
[System.Serializable]
public class FolderPack
{
    public List<Folder> Folders;
}

引发的错误:

  

JsonSerializationException:反序列化对象时出现意外的标记:StartObject。 Path&#39; ComplexData [1]&#39;,第14行,第9位。

我的猜测是JsonConvert只能直接处理第一级,并委托所有其他可序列化类的反序列化。只有它处理铸造而其他人因上述错误而失败。

注意: Folders的列表,但在根级别也可以。

1 个答案:

答案 0 :(得分:0)

根据提供的信息,以下最小的例子是由模型的对象图构成的,

public class StartObject {
    public List<FolderPack> ComplexData { get; set; }
}

[System.Serializable]
public class FolderPack {
    public List<Folder> Folders { get; set; }
}

public class Folder {
    public string Path { get; set; }
    public string ExtraInfo { get; set; }

    public static implicit operator Folder(string path) {
        return new Folder(path);
    }

    public Folder() {

    }

    public Folder(string path) {
        this.Path = path;
    }
}

请注意使用属性而不是字段。还使用implicit运算符而不是explicit运算符。

经过测试并按预期通过。

[TestClass]
public class Test {
    [TestMethod]
    public void JsonConvert() {
        var json = @"{
            ""ComplexData"" : [
                {
                    ""Folders"" : [
                         ""path/to/A"",
                         ""path/to/B"" // Same here
                     ]
                },
                {
                    ""Folders"" : []
                }
             ]
        }";
        var result = JsonConvert.DeserializeObject<StartObject>(json);

        result.Should().NotBeNull();
        result.ComplexData[0].Folders[1].Path.Should().Be("path/to/B");
    }
}