我正在尝试将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)..
答案 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类的开头,它开始工作并保存数据(对函数的修改也很少)。