2017-05-25 42 views
1

我尝试使用Newtonsoft.json为了反序列化json文件的汇编。 我有我的C#类对应的模式,工作很好。 如果我把所有的json文件放在一个,它反序列化没有任何问题,但我想有一些可读的文件。要做到这一点,我已经把它们分成了多个文件。反序列化多个json文件

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

例如,我有在应用下面的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文件之间的链接,或者如果它是别的东西。 有一点帮助会受到欢迎:-)

+0

当您尝试,它实际上会发生什么? – Abion47

+0

Newtonsoft无法反序列化您的json文件,因为它无效json https://jsonlint.com/ –

+0

具体来说,第二个文件的JSON由于第二个''dataModel“''末尾的额外逗号而无效。 – Abion47

回答

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(); 
    } 
} 
+0

谢谢@ Abion47,它工作正常。 – kadben

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 
}); 
+0

当我尝试你的解决方案时,我得到和异常:Newtonsoft.Json.JsonReaderException:'无效的属性标识符字符:{。路径'',第1行,位置1'。 – kadben

0

单个对象合并文件后,现在引用的作品。所以我认为无法使用JsonConvert解析引用。