Json.net: Serialisierung / Deserialisierung funktioniert nicht für ISerializable-Objekte mit Zirkelbezug

Vor einiger Zeit habe ich eineProblem für die ich eine Verlegenheit in Json.net 4.5 R11 habe.

Wenn mein Rundschreiben auf Eigentum verweistManager NULL ist, dann funktioniert Serialisierung und Deserialisierung einwandfrei.

Aber wenn ZirkelreferenzeigenschaftManager Wird der Wert auf NON NULL gesetzt, wird er in der serialisierten Zeichenfolge ignoriert und löst daher eine Ausnahme bei der Deserialisierung aus.

Json.net Issue Base sagt, dass das Problem in Ihrem Code liegt, aber ich konnte es nicht herausfinden. Kann mir hier jemand helfen?

Fragen:

Gibt es ein Problem mit dem folgenden Code?Wenn ja, was soll ich tun, um das Problem zu lösen?Wenn nicht, was sollte in Json.net-Code getan werden, um dieses Problem zu lösen?

Noch ein paar Updates: Dies wird in der Legacy-Anwendung benötigt, die derzeit die binäre Serialisierung verwendet. Da die Änderungen sehr umfangreich sind, ist das Markieren aller privaten Felder, die an der Serialisierung beteiligt sind, mit dem Json-Serialisierungstag zu aufwendig. Da Json.net eine Serialisierung von ISerializable-Objekten durchführen kann, möchten wir dies tun. Dies funktioniert, wenn keine kreisförmigen Referenzobjekte vorhanden sind.

Meine Klassen

[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 );
    }
}

Mein Testcode:

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

Antworten auf die Frage(4)

Ihre Antwort auf die Frage