しばらく前に、Json.net 4.5 R11 で修正された問題を報告しました。
循環参照プロパティManager
が NULL の場合、シリアル化と逆シリアル化は正常に機能します。
ただし、循環参照プロパティManager
が NON NULL 値に設定されている場合、シリアル化された文字列では無視されるため、逆シリアル化で例外がスローされます。
Json.netの問題ベースは、問題はあなたのコードにあると言いますが、私は理解できませんでした。誰かがここで私を助けることができますか?
質問:
- 以下のコードに問題はありますか?
- はいの場合、問題を解決するにはどうすればよいですか?
- そうでない場合、この問題を解決するために Json.net コードで何をすべきでしょうか?
その他の更新: これは、現在バイナリ シリアル化を使用しているレガシー アプリケーションで必要です。変更は膨大であるため、シリアライゼーションに関係するすべてのプライベート フィールドを Json シリアライゼーション タグでマークするのは大変な作業です。Json.net は ISerializable オブジェクトのシリアル化を行うことができるので、これを行いたいと考えています。これは、循環参照オブジェクトがない場合に機能します。
私のクラス
[Serializable]
class Department : ISerializable
{
public Employee Manager { get; set; }
public string Name { get; set; }
public Department() { }
public Department( SerializationInfo info, StreamingContext context )
{
Manager = ( Employee )info.GetValue( "Manager", typeof( Employee ) ); //Manager's data not found since json string itself does not have Employee property
Name = ( string )info.GetValue( "Name", typeof( string ) );
}
public void GetObjectData( SerializationInfo info, StreamingContext context )
{
info.AddValue( "Manager", Manager );
info.AddValue( "Name", Name );
}
}
[Serializable]
class Employee : ISerializable
{
public Department Department { get; set; }
public string Name { get; set; }
public Employee() { }
public Employee( SerializationInfo info, StreamingContext context )
{
Department = ( Department )info.GetValue( "Department", typeof( Department ) );
Name = ( string )info.GetValue( "Name", typeof( string ) );
}
public void GetObjectData( SerializationInfo info, StreamingContext context )
{
info.AddValue( "Department", Department );
info.AddValue( "Name", Name );
}
}
私のテストコード:
JsonSerializerSettings jsonSS= new JsonSerializerSettings();
jsonSS.Formatting = Formatting.Indented;
jsonSS.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; //If there is referenced object then it is not shown in the json serialisation
//jsonSS.ReferenceLoopHandling = ReferenceLoopHandling.Serialize; //Throws stackoverflow error
jsonSS.PreserveReferencesHandling = PreserveReferencesHandling.All;
Department department = new Department();
department.Name = "Dept1";
Employee emp1 = new Employee { Name = "Emp1", Department = department };
department.Manager = null;
string json1 = JsonConvert.SerializeObject( emp1, jsonSS );
//json1 =
// {
// "$id": "1",
// "Department": {
// "$id": "2",
// "Manager": null,
// "Name": "Dept1"
// },
// "Name": "Emp1"
//}
Employee empD1 = JsonConvert.DeserializeObject<Employee>( json1, jsonSS ); //Manager is set as null
department.Manager = emp1; //Non null manager is set
string json2 = JsonConvert.SerializeObject( emp1, jsonSS ); //SEE Manager property is missing
// json2 = {
// "$id": "1",
// "Department": {
// "$id": "2",
// "Name": "Dept1"
// },
// "Name": "Emp1"
//}
Employee empD2 = JsonConvert.DeserializeObject<Employee>( json2, jsonSS ); //Throws exception