Как исправить ошибку self referencing loop detected при создании json-файла?

Рейтинг: 0Ответов: 1Опубликовано: 11.05.2023

Необходимо создать файл json со всеми значениями List<Control>. List<Control> принимает свои значения в методе GetPictureElements(), код метода:

public List<Control> GetPicureElements()
        {
            List<Control> list = new List<Control>();
            foreach (Control control in pictureBoxMain.Controls)
            {
                list.Add(control);
            }
            return list;
        }

Далее создан класс для хранения полученного списка:

namespace projectws
{
    [Serializable]
    public class EL
    {
        private List<Control> _el;
        [DataMember]
        public List<Control> El
        {
            get => _el;
            set => _el = value;
        }
        public EL(List<Control> el)
        {
            El = el;
        }
    }
}

Ошибка "Self referencing loop detected for property 'Owner' with type 'System.Windows.Forms.Label'. Path 'El[0].AccessibilityObject'." возникает в коде создания json файла:

private void buttonSaveVersion_Click(object sender, EventArgs e)
        {
            var el = new EL(GetPicureElements());
            string json = JsonConvert.SerializeObject(el); //ошибка тут
            System.IO.File.WriteAllText("test.json", json);
        }

Примечание: List<Control> имеет некоторое нестатичное количество элементов Label, добавляемых пользователем в PictureBox, соответсвенно ошибку выдаёт первый ([0]) полученный из списка Label

Ответы

▲ 0Принят

Контролы сериализовать не получится. Создавайте структуры данных для сериализации, атрибуты здесь тоже не нужны.

public List<string> GetLabelsTexts()
{
    List<string> result = new List<string>();
    foreach (Label label in pictureBoxMain.Controls.OfType<Label>())
    {
        result.Add(label.Text);
    }
    return result;
}
List<string> items = GetLabelsTexts();
string json = JsonConvert.SerializeObject(items);
File.WriteAllText("test.json", json);

Можно хоть с координатами

public class LabelInfo
{
    public Point Location { get; set; }
    public string Text { get; set; }
}
public List<LabelInfo> GetLabelsInfo()
{
    List<LabelInfo> result = new List<LabelInfo>();
    foreach (Label label in pictureBoxMain.Controls.OfType<Label>())
    {
        result.Add(new LabelInfo
        {
            Text = label.Text,
            Location = label.Location
        });
    }
    return result;
}
List<LabelInfo> items = GetLabelsInfo();
string json = JsonConvert.SerializeObject(items);
File.WriteAllText("test.json", json);

Десериализовать обратно так же легко

string json = File.ReadAllText("test.json");
List<LabelInfo> items = JsonConvert.DeserializeObject<List<LabelInfo>>(json);
pictureBoxMain.Controls.Clear();
foreach (LabelInfo info in items)
{
    pictureBoxMain.Controls.Add(new Label
    {
        Text = info.Text,
        Location = info.Location
    });
}