我有以下对象要序列化为JSON字符串:
public class Zone
{
public string id;
public string name;
public Size size;
public Point offset;
public List<Label> zoneLabels;
}
在添加之前,我能够很好地使用以下内容:
public List<Label> zoneLabels;
string json;
json = JsonConvert.SerializeObject(zn);
当我添加:
public List<Label> zoneLabels;
并运行 json = JsonConvert.SerializeObject(zn(;我收到以下错误:
{"检测到具有类型的属性"所有者"的自引用循环 "System.Windows.Forms.Label"。路径 '区域标签[0]。AccessibilityObject'."}
基本上,我的 Zone 对象包含一些如下所示的属性和一个标签控件列表。我需要将其序列化为 JSON 字符串,稍后恢复到相同的区域对象(将对象反序列化为区域(。我需要做什么不同的事情?
对象时可以使用 Newtonsoft.Json.ReferenceLoopHandling.Ignore 。
json = JsonConvert.SerializeObject(zn, Formatting.Indented,
new JsonSerializerSettings() {
ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
}
);
您还有其他ReferenceLoopHandling
枚举,您可以根据需要使用这些枚举。
正如 OP 评论的那样,在使用上述代码后,OP 会得到 Stackoverflow 异常,这是由于标签无限期嵌套造成的。因此,在这种情况下,您可以使用 PreserveReferencesHandling.Objects
json = JsonConvert.SerializeObject(zn, Formatting.Indented,
new JsonSerializerSettings()
{
PreserveReferencesHandling = PreserveReferencesHandling.Objects
});
经过一些研究和其他回应,我发现处理这个问题的最佳方法是制作自己的标签对象,例如:
public class Zone
{
public string id;
public string name;
public Size size;
public Point offset;
public List<ZoneLabels> zoneLabels;
}
public class ZoneLabels
{
public string text;
public string name;
public Point location;
}
然后,您可以使用 JSON.NET 轻松执行以下操作以序列化为 JSON 字符串
List<ZoneLabels> labels_list = new List<ZoneLabels>();
foreach (Label zl in znLabels)
{
labels_list.Add(new ZoneLabels { name = zl.Name, text = zl.Text, location = zl.Location });
}
Zone zn = new Zone();
zn.name = "Zone";
zn.size = new Size(464, 128);
zn.offset = new Point(x, y);
zn.id = id_new;
zn.zoneLabels = labels_list;
//serialize the object to a JSON string
string json = JsonConvert.SerializeObject(zn);
这将生成一个 JSON 字符串,该字符串将反序列化回 Zone 对象。
就我而言,我只设置了标签的一些属性,但即使您需要设置多个控件对象属性,这可能是处理将表单控件对象列表序列化为 JSON 字符串的最清晰方法之一。