C# 序列化不会向 xml 文件中的属性添加值

标签 c# winforms .net-core .net-6.0

我是编程新手,但我需要序列化数据,我首先读取 csv 并根据所述 csv 中的数据创建类。当我单击按钮时,列表应该被序列化以供以后使用。

这是 Dealership (del) 和 Car 类的代码:

[DataContract]
public class Dealership
{
    [DataMember]
    private List<Car> carList = new List<Car>();
        
    public void ImportCars()
    {
        carList.Clear();

        var fileContent = string.Empty;
        var filePath = string.Empty;

        using (OpenFileDialog openFileDialog = new OpenFileDialog())
        {
            openFileDialog.InitialDirectory = "c:\\";
            openFileDialog.Filter = "csv files (*.csv)|*.csv";

            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                filePath = openFileDialog.FileName;

                using (var reader = new StreamReader(filePath))
                using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
                {
                    csv.Read();
                    csv.ReadHeader();
                    while (csv.Read())
                    {
                        var record = new Car
                        {
                            Model = csv.GetField("model"),
                            Brand = csv.GetField("brand"),
                            Year = Convert.ToInt32(csv.GetField("year")),
                            Price = Convert.ToDecimal(csv.GetField("price"))
                        };
                        carList.Add(record);
                    }
                }
            }
        }
    }
}

[DataContract]
public class Car
{
    [DataMember]
    private string brand;
    [DataMember]
    private string model;
    [DataMember]
    private int year;
    [DataMember]
    private decimal price;

    public string Brand { get; set; }

    public string Model { get; set; }

    public int Year { get; set; }

    public decimal Price { get; set; }
}

这是表单代码:

Dealership del1 = del;

FileStream? fs = null;

try
{
    fs = new FileStream("dealership.xml", FileMode.OpenOrCreate, FileAccess.Write);

    Type mainType = typeof(Dealership);
    //List<Type> auxiliryTypes = new List<Type>() { typeof(Car), typeof(Customer) };
    DataContractSerializer dcs = new DataContractSerializer(mainType);

    dcs.WriteObject(fs, del1);
}
finally
{
    if (fs!=null) fs.Close();
}

XML 输出片段:

<Dealership xmlns="http://schemas.datacontract.org/2004/07/Individual_Assignment" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><carList><Car><brand i:nil="true"/><model i:nil="true"/><price>0</price><year>0</year></Car>

当我通过在表单中​​输入客户详细信息来销售汽车时,XML 怎么可能不包含汽车的任何值,它会序列化这些值,但不会序列化其他值。

最佳答案

根据经验,让数据传输对象 (DTO) 类(即用于序列化的类)仅具有公共(public)属性。您可能还应该使用通用集合:

[DataContract] 
public class Dealership { 
    [DataMember] 
    public List<Car> CarList {get;set;} = new List<Car>();
}

使用公共(public)属性往往适用于大多数序列化库。可能存在异常(exception),有些可以处理私有(private)属性,有些可以处理不可变类型,但是您需要检查您的库支持哪些特定语法。我不记得 DataContractSerializer 的确切规则。

另请注意,您可能应该将 DTO 类与域类分开,这样您在实际使用对象时不必公开内部字段,只有在与系统的其他部分通信时才需要公开内部字段。

我还建议设置一个单元测试来序列化和反序列化您的类。这是查看哪些有效、哪些无效的简单方法。如果您担心的话,它还可以用于检查旧版本的类是否仍然正确地反序列化。

完整示例:

[DataContract]
public class Car
{
    [DataMember]
    public string Brand { get; set; }
    [DataMember]
    public string Model { get; set; }
    [DataMember]
    public int Year { get; set; }
    [DataMember]
    public decimal Price { get; set; }
}

[DataContract]
public class Dealership
{
    [DataMember] 
    public List<Car> Cars { get; set; } = new ();
};


[Test]
public void ShouldSerializeAndDeserialize()
{
    var sut = new DataContractXml();
    var car = new Car(){Brand = "Volvo", Model = "v70", Price = 20000, Year = 2004};
    var dealer = new Dealership();
    dealer.Cars.Add(car);

    using var ms = new MemoryStream();
    
    var serializer = new DataContractSerializer(typeof(Dealership));
    serializer.WriteObject(ms, dealer);
    ms.Position = 0;
    var result = (Dealership)serializer.ReadObject(ms);

    Console.WriteLine(result.Cars[0].Brand);
}

关于C# 序列化不会向 xml 文件中的属性添加值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75081234/

相关文章:

C# 调用 python 解释器

c# - 生成数字并在内存中选择

c# - 我们可以设置面板背景图像的不透明度吗?

c# - List<Bar> 的 Json 反序列化中的属性 setter

c# - Entity Framework Core 忽略 .Include(..) 而没有 .ToList(..) 间接

c# - 显示月份名称的 DataAnnotation

c# - 检测我的测试是否在 Visual Studio Team Services 上运行

c# - 如何使用 TreeView.AfterSelect 和 TreeView.DrawNode 方法?

c# - 从指定时间开始秒表

c# - .net core 2.1 log4net 多环境