反序列化多个json文件

时间:2017-05-25 08:55:09

标签: c# json serialization json.net

我尝试使用 Newtonsoft.json 来反序列化json文件的汇编。 我的C#类对应于运行良好的模式。 如果我把所有的json文件放在一个,它反序列化没有任何问题,但我想有一些可读的文件。为此,我将它们分成多个文件。

当我这样做时,即使它们之间存在链接, Newtonsoft.json 也无法使用相应的架构创建完整的模型。

例如,我在Application中有以下C#类,如下所示DataModel

class Application
{
    [JsonProperty("dataModel", NullValueHandling = NullValueHandling.Ignore)]
    public DataModel dataModel { get; set; }
}

class DataModel
{
    [JsonProperty("id", Required = Required.Always)]
    public String id { get; set; }
}

和我要反序列化的json是:

  • application.json:

    {
      "dataModel": {"$ref":"data.json"}
    }
    
  • data.json:

    {
      "$id": "dataModel",
      "id": "dataModel",
    }
    

我执行代码行来反序列化:

JsonConvert.DeserializeObject(File.ReadAllText(@"application.json"),
   new JsonSerializerSettings {
   PreserveReferencesHandling = PreserveReferencesHandling.None,
   ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});

之后,我只检查我的应用是否有DataModel,但我得到一个例外情况,告诉我 DataModel为空

我不知道问题是否是因为 Newtonsoft 无法在简单的json文件之间建立链接,或者它是否是其他内容。 欢迎提供一些帮助: - )

3 个答案:

答案 0 :(得分:0)

这很简单。你需要的只是一个包装类。像这样的东西:

class Wrapper
{
    class Application
    {
        [JsonProperty("dataModel", NullValueHandling = NullValueHandling.Ignore)]
        public DataModel dataModel { get; set; }
    }

    class DataModel
    {
        [JsonProperty("id", Required = Required.Always)]
        public String id { get; set; }
    }
}

然后试试这个:

JsonConvert.DeserializeObject("{"+File.ReadAllText(@"application.json")+"}",
   new JsonSerializerSettings {
   PreserveReferencesHandling = PreserveReferencesHandling.None,
   ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});

答案 1 :(得分:0)

合并单个对象中的文件后,现在引用有效。所以我认为用JsonConvert解析引用是不可能的。

答案 2 :(得分:0)

我还没有找到解决问题的正确方法。与此同时,也许你可以以自定义转换器的形式做一个解决方法。

你的课程:

class Application
{
    public DataModel dataModel { get; set; }
}

[JsonConverter(typeof(DataModelConverter))]
class DataModel
{
    public String id { get; set; }
}

DataModelConverter.cs

class DataModelConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(DataModel);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var jobj = JObject.Load(reader);

        if (jobj["$ref"] != null)
        {
            string path = jobj["$ref"].Value<string>();
            string json = File.ReadAllText(path);
            return JsonConvert.DeserializeObject<DataModel>(json);
        }

        var model = new DataModel
        {
            id = jobj.Value<string>("id")
        };

        return model;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var model = value as DataModel;

        string path = "data.json";
        string json = $"{{\r\n\t\"$id\" : \"{model.id}\",\r\n\t\"id\" : \"{model.id}\"\r\n}}";
        File.WriteAllText(path, json);

        writer.WriteStartObject();
        writer.WritePropertyName("$ref");
        serializer.Serialize(writer, path);
        writer.WriteEndObject();
    }
}