Serialisieren/Deserialisieren Sie eine Referenz von iSerializierbaren Objekten mit Newtonsoft.json (JSON.net)
Posted: 12 Jul 2025, 22:48
Präambel: Ich weiß über iSerializable Abschaltung. Wir müssen es verwenden, weil wir eine massive Legacy -Codebasis für IPC haben (die diese Schnittstelle verwendet). Wir migrieren von .NET Remoting zu einer Cross -Plattform -Lösung. Und wir planten, vorhandene Codebasis -Setups beizubehalten, wenn es möglich ist.
und Ich haben eine .NET 8.0 -Konsolenanwendung, auf die sich auf Newtonsoft.json verweist und diese Klassen serialisiert/deserialisiert
System.runtime.Serialization.SerializationException: Mitglied 'DefaultUser' wurde nicht gefunden. /> Der JSON ist < /p>
findet defaultUser nicht. Ich kann eine Workaround -Erweiterungsmethode serializationInfo implementieren. So etwas wie: < /p>
kann mir helfen?
Beispielprojekt Repo.
Flag Es wird diese Ausnahme abgerufen:
System.StackoverFlowexception: Ausnahme des Typs 'System.StackoverFlowexception' wurde geworfen. Die Option erzeugt JSON, die ich brauche, aber sie unterstützt nicht iSerializable daher ist es für mich nicht geeignet. Darüber hinaus hat System.text.json eigene Nachteile, beispielsweise keine automatische Handhabung. Ich muss meine Basisdatenklassen und Schnittstellen mit JSONDEVIVedTypeTtribute markieren. Das 1) fügt meiner Klassenbibliothek eine externe Abhängigkeit hinzu (ich versuche sie zu vermeiden).>
Code: Select all
using System;
using System.Runtime.Serialization;
namespace DataClasses
{
[Serializable]
internal sealed class User : ISerializable
{
public string Name { get; set; }
public UserGroup Group { get; set; }
internal User()
{}
private User(SerializationInfo info, StreamingContext context)
{
Name = (string)info.GetValue(nameof(Name), typeof(string));
Group = (UserGroup)info.GetValue(nameof(Group), typeof(UserGroup));
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue(nameof(Name), Name);
info.AddValue(nameof(Group), Group);
}
}
[Serializable]
internal sealed class UserGroup : ISerializable
{
public string Name { get; set; }
public User DefaultUser { get; set; }
internal UserGroup()
{ }
private UserGroup(SerializationInfo info, StreamingContext context)
{
Name = (string)info.GetValue(nameof(Name), typeof(string));
DefaultUser = (User)info.GetValue(nameof(DefaultUser), typeof(User));
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue(nameof(Name), Name);
info.AddValue(nameof(DefaultUser), DefaultUser);
}
}
}
Code: Select all
using Newtonsoft.Json;
namespace NewtonsoftJSONTest
{
internal class Program
{
static void Main(string[] args)
{
var user = new DataClasses.User { Name = "User" };
var group = new DataClasses.UserGroup { Name = "Group", DefaultUser = user };
user.Group = group;
var settings = new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
var json = JsonConvert.SerializeObject(user, settings);
var userRestored = JsonConvert.DeserializeObject(json);
}
}
}
< /code>
Mit dieser Konfiguration erhalte ich eine Ausnahme in der Zeile: < /p>
DefaultUser = (User)info.GetValue(nameof(DefaultUser), typeof(User));
Code: Select all
{
"Name": "User",
"Group": { "Name": "Group" }
}
< /code>
Also der Code in Zeile < /p>
DefaultUser = (User)info.GetValue(nameof(DefaultUser), typeof(User));
Code: Select all
{
"Name": "User",
"Group": {
"Name": "Group",
"DefaultUser": null
}
}
< /code>
Eine Lösung, die keine Newtonsoft.json -Attribute verwendet, wird sehr geschätzt, da ich nicht möchte, dass meine Klassenbibliothek externe Abhängigkeiten hat. Vielleicht ein benutzerdefiniertes Contractresolver
Beispielprojekt Repo.
Code: Select all
ReferenceLoopHandling = ReferenceLoopHandling.Serialize
System.StackoverFlowexception: Ausnahme des Typs 'System.StackoverFlowexception' wurde geworfen. Die Option erzeugt JSON, die ich brauche, aber sie unterstützt nicht iSerializable daher ist es für mich nicht geeignet. Darüber hinaus hat System.text.json eigene Nachteile, beispielsweise keine automatische Handhabung. Ich muss meine Basisdatenklassen und Schnittstellen mit JSONDEVIVedTypeTtribute markieren. Das 1) fügt meiner Klassenbibliothek eine externe Abhängigkeit hinzu (ich versuche sie zu vermeiden).>