类序列化导致外部库中的stackOverflowException

时间:2017-12-14 19:39:20

标签: c# serialization

我正在尝试将BindingList序列化/反序列化为XML文件,但总是出错:

  

未处理的类型' System.StackOverflowException'发生在System.Xml.dll

据我所知,它是由于一些无效的引用(get,set,return this)和无限的recurssions引起的。浪费了两天没有成功。

数据使用BindingSource和BindingList绑定在一起,也显示在dataGridView中。

我初始化所有可序列化的类:

public Person persons = new Person();

我创建了bindingSources:

BindingSource bsPerson = new BindingSource();

在main函数中,我创建了添加了项目的所有BindingLists:

BindingList<Person> persons = new BindingList<Person>()
{
    new Person()
    {
        Surname = "Abc", Phone = "123",
        Address = "Street 1",
        Email = "some@domain.com",
        Car = new BindingList<Car>() { cars[0], cars[1]} }
};

这是我的可序列化类:

[Serializable]
public class Person : BindingList<Person>
{
    public string Surname { get; set; }
    public string Phone { get; set; }
    public string Addres { get; set; }
    public string Email { get; set; }
    public BindingList<Car> Car { get; set; }

    public Person()
    {
        Car = new BindingList<Car>();
    }
}

[Serializable]
public class Car
{
    public string Model { get; set; }
    public int Mileage { get; set; }
    public DateTime ManufactureDate { get; set; }
    public int WheelCount { get; set; }
    public string FuelType { get; set; }
    public int Seats { get; set; }
    public GearBox GearBox { get; set; }
    public Car self { get { return this; } }
}

[Serializable]
public class GearBox
{
    public string Name { get; set; }
    public int CountOfTransfers { get; set; }
    public string Type { get; set; }
    public GearBox self {get {return this;} }
}

[Serializable]
public class ServiceVisits
{
    public DateTime ServiceInDate { get; set; }
    public DateTime ServiceOutDate { get; set; }
    public double Bill { get; set; }
    public string EmployeeName { get; set; }
    public BindingList<ServiceParts> ServiceParts { get; set; }

    public ServiceVisits()
    {
        ServiceParts = new BindingList<ServiceParts>();
    }

    public Company Company { get; set; }
    public Car Car { get; set; }
}

[Serializable]
public class Company
{
    public string Name { get; set; }
    public string Phone { get; set; }
    public int VatNumber { get; set; }
    public string Address { get; set; }
    public Company self { get { return this; } }

}

[Serializable]
public class ServiceParts
{
    public string Name { get; set; }
    public double Price { get; set; }
}

这就是我调用序列化函数的方法:

Serializeri.Serializacija<Person>(persons, path);

这就是我调用反序列化函数的方法:

Serializeri.Deserializacija<Person>(persons, path);

这是包含序列化/反序列化函数的类:

public static class Serializeri
{
    public static void Serializacija<T>(this BindingList<T> list, string       path)
    {
        try
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "XML Faili (*.xml) | *.xml";

            if (sfd.ShowDialog() == DialogResult.OK)
            {
                XmlSerializer srz = new XmlSerializer(typeof(BindingList<T>));
                XmlWriter xw = XmlWriter.Create(sfd.FileName);
                srz.Serialize(xw, list);
                xw.Flush();
                xw.Close();
            }
        }
        catch (IOException)
        {
            MessageBox.Show("Nevar saglabāt failu, jo to izmanto cits process!", "Kļūda", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

    public static void Deserializacija<T>(this BindingList<T> list, string path)
    {
        try
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "XML Faili (*.xml) | *.xml";

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                XmlSerializer srz = new XmlSerializer(typeof(BindingList<T>));
                XmlReader xr = XmlReader.Create(ofd.FileName);

                var obj = (BindingList<T>)(srz.Deserialize(xr));

                list.Clear();

                foreach (var element in obj)
                {
                    list.Add(element);
                }

                xr.Close();                    
            }
        }
        catch (IOException)
        {
            MessageBox.Show("Nevar atvērt failu, jo to izmanto cits process!", "Kļūda", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }
}

如何修复它以便序列化工作?我对界面不是很熟悉,如果我现在可以避免使用它们会很好。

调试后我发现有时数据没有正确添加。它显示在dataGridView中,但实际的BindingList为空(count = 0)..

2 个答案:

答案 0 :(得分:3)

Person没有理由成为自己的集合。无论如何,你永远不会把它当作自己的集合使用,所以如果你不做它就不会有任何损失。当我从BindingList<Person>中删除基类Person时,序列化不再无限地递归。

public class Person 
{

答案 1 :(得分:0)

问题是我在Main函数中定义了function fetchuserStatus($username,$password){ include("db-settings.php"); $sql = "SELECT * from _yb_all_users_tbl where User_name = ? AND Password = ?"; $parameters = array($username,$password); $stmt = sqlsrv_prepare($conn, $sql, $parameters); sqlsrv_execute($stmt); if(!$stmt) { die( print_r( sqlsrv_errors(), true)); } while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) ) { return $row; } sqlsrv_free_stmt($stmt); sqlsrv_close($conn); } 和所有其他列表。基本上我的Serialize / Deserialzie函数访问的是类的实例(与BindingLists同名)而不是真正的列表。

我将BindingList<Person>移到Main类的开头,它开始工作并保存数据(对函数的修改也很少)。