2016-01-08 20 views
0

JSON.NET(使用設置PreserveReferencesHandling = PreserveReferencesHandling.Objects)首次出現序列化嵌入的重複出現對象並在隨後出現時將其串行化爲JSON引用。 我猜這是爲了避免前向引用。如何使JSON.NET在序列化期間呈現前向引用

例如:

class Person 
{ 
    public string Name { get; set; } 
    public Person Mother { get; set; } 
} 

var joni = new Person { Name = "Joni" }; 
var james = new Person { Name = "James", Mother = joni }; 

var people = new List<Person> { james, joni }; 

var json = JsonConvert.SerializeObject(people, Formatting.Indented, 
    new JsonSerializerSettings { 
     PreserveReferencesHandling = PreserveReferencesHandling.Objects }); 

結果如下:

[ 
    { 
    "$id": "1", 
    "Name": "James", 
    "Mother": { 
     "$id": "2", 
     "Name": "Joni", 
     "Mother": null 
    } 
    }, 
    { 
    "$ref": "2" 
    } 
] 

相反,我希望得到這樣的:

[ 
    { 
    "$id": "1", 
    "Name": "James", 
    "Mother": { 
     "$ref": "2" 
    } 
    }, 
    { 
    "$id": "2", 
    "Name": "Joni", 
    "Mother": null  
    } 
] 

雖然兩者都是有效平等的,我發現第二個更合理,特別是在手工編輯JSON數據時(這是我在這件事上的一個用例) 。

有沒有辦法控制哪個實例被序列化爲引用或者我堅持這種第一次出現的行爲?

編輯

我試圖反序列化JSON所需,發現JSON.NET沒有做到這一點,因爲正確的正向引用。

+2

你被困住了。爲了做到你想做的事情,Json.NET將無法做到單流傳輸讀取和解析JSON。它需要將整個內容加載到內存中(比如說,到一個JToken層次結構中),創建一個查找數據庫,然後反序列化。我想你可以做這樣的事情:序列化爲'JToken',將''$ id「'節點從第一次出現移動到最淺處,然後保存;然後稍後做反序列化。 – dbc

+1

@dbc謝謝,我想我最好放開它,因爲這次麻煩似乎不值得。 –

回答

-1

發生什麼事是你在Person變量中實例化一個Person變量。所以,當你創建的「兒子」:

class Person 
{ 
    public string Name { get; set; } 
    public Person Mother { get; set; } 
} 

您正在創建內部母親變數,這是一個人類型的變量,並擁有所有的屬性,一個普通的人,變量將具有與所產生的JSON文件你正在獲得。

您可以嘗試創建一個從類「Person」繼承而來的僅具有ID屬性的新類「Mother」,因此當您創建JSON文件時,您將獲得預期的結果。