Newtonsoft.Json高階篇:TypeNameHandling設定

tinys發表於2019-02-21

此示例使用TypeNameHandling 設定在序列化JSON和讀取型別資訊時包含型別資訊,以便在反序列化JSON時建立建立型別

Sample

public abstract class Business
{
    public string Name { get; set; }
}

public class Hotel : Business
{
    public int Stars { get; set; }
}

public class Stockholder
{
    public string FullName { get; set; }
    public IList<Business> Businesses { get; set; }
}

使用

Stockholder stockholder = new Stockholder
{
    FullName = "Steve Stockholder",
    Businesses = new List<Business>
    {
        new Hotel
        {
            Name = "Hudson Hotel",
            Stars = 4
        }
    }
};

string jsonTypeNameAll = JsonConvert.SerializeObject(stockholder, Formatting.Indented, new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.All
});

Console.WriteLine(jsonTypeNameAll);
// {
//   "$type": "Newtonsoft.Json.Samples.Stockholder, Newtonsoft.Json.Tests",
//   "FullName": "Steve Stockholder",
//   "Businesses": {
//     "$type": "System.Collections.Generic.List`1[[Newtonsoft.Json.Samples.Business, Newtonsoft.Json.Tests]], mscorlib",
//     "$values": [
//       {
//         "$type": "Newtonsoft.Json.Samples.Hotel, Newtonsoft.Json.Tests",
//         "Stars": 4,
//         "Name": "Hudson Hotel"
//       }
//     ]
//   }
// }

string jsonTypeNameAuto = JsonConvert.SerializeObject(stockholder, Formatting.Indented, new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.Auto
});

Console.WriteLine(jsonTypeNameAuto);
// {
//   "FullName": "Steve Stockholder",
//   "Businesses": [
//     {
//       "$type": "Newtonsoft.Json.Samples.Hotel, Newtonsoft.Json.Tests",
//       "Stars": 4,
//       "Name": "Hudson Hotel"
//     }
//   ]
// }

// for security TypeNameHandling is required when deserializing
Stockholder newStockholder = JsonConvert.DeserializeObject<Stockholder>(jsonTypeNameAuto, new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.Auto
});

Console.WriteLine(newStockholder.Businesses[0].GetType().Name);
// Hotel

具體內容詳見官方文件:https://www.newtonsoft.com/json/help/html/SerializeTypeNameHandling.htm

解決的具體問題:可以支援複雜的繼承結構:

string jsonTypeNameAll = JsonConvert.SerializeObject(xx, Formatting.Indented, new JsonSerializerSettings
    {
        TypeNameHandling = TypeNameHandling.All,
        ReferenceLoopHandling = ReferenceLoopHandling.Ignore
    });

    var oo= JsonConvert.DeserializeObject<StartConfig>(File.ReadAllText(path), new JsonSerializerSettings
    {
        TypeNameHandling = TypeNameHandling.All,
        ReferenceLoopHandling = ReferenceLoopHandling.Ignore
    });
    ISupportInitialize iSupportInitialize = (ISupportInitialize) oo;
    iSupportInitialize?.EndInit();

    var o9=oo.GetComponent<InnerConfig>();//例項化StartConfig物件的子物件

 

相關文章