序列化多个对象错误:对象未设置为实例

本文关键字:对象 设置 实例 错误 序列化 | 更新日期: 2023-09-27 17:55:14

我正在尝试为我的应用程序创建一个可重用的序列化程序/反序列化程序,并且遇到"对象引用未设置为对象的实例"错误,我不明白为什么。

这是我的序列化程序代码:

[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "ReportAutomation Test Application", IsNullable = false)]
public class ReportSpec{
    [System.Xml.Serialization.XmlElementAttribute("Report")]
    public List<ReportsHolder> ReportsList { get; set; }
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public double Version { get; set; }
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string Username { get; set; }
}
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public class ReportsHolder{
    public List<FirstClass> FirstClassReportsList { get; set; }
    public List<SecondClass> SecondClassReportList { get; set; }
}
public class BaseClass{
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string ReportName { get; set; }
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string FilterMode { get; set; }
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string Destination { get; set; }
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string Format { get; set; }
}
public class FirstClass : BaseClass{
    public string AlertSource { get; set; }
    public bool ShouldSerializeAlertSource(){
        return AlertSource != null;
    }
}
public class SecondClass : BaseClass{
    public int? DeviceID;
    public bool ShouldSerializeDeviceID(){
        return DeviceID != null;
    }
}

这是我尝试创建XML文件的地方:

    private string outputPath = @"C:'temp'ReportAutomationTest.xml";
        private void CreateFile(){
            XmlSerializer serializer = new XmlSerializer(typeof(ReportSpec));
            TextWriter writer = new StreamWriter(outputPath);
            // create the root object
            ReportSpec myReportSpec = new ReportSpec{ Username = "My Name", Version = 4.5 };
            // create the report holder
            ReportsHolder myReportsHolder = new ReportsHolder();
            // create a FirstClass object
            FirstClass myFirstClass = new FirstClass();
            myFirstClass.ReportName = "Base Camp Report";
            myFirstClass.FilterMode = "Container";
            myFirstClass.Destination = "someone@somewhere.com";
            myFirstClass.Format = "PDF";
            myFirstClass.AlertSource = "Base Camp 1";

            // add myFirstClass to the FirstClassList
            myReportsHolder.FirstClassReportsList.Add(myFirstClass);  // <-- Object reference not set to an instance of an object.
            // create another FirstClass object
            FirstClass anotherFirstClass = new FirstClass();
            anotherFirstClass.ReportName = "Satellite Stations Report";
            anotherFirstClass.FilterMode = "Container";
            anotherFirstClass.Destination = @"''path'on'my'network";
            anotherFirstClass.Format = "DOC";
            anotherFirstClass.AlertSource = "Satellite Station 1";
            // add myFirstClass to the FirstClassList
            myReportsHolder.FirstClassReportsList.Add(anotherFirstClass);

            // create a SecondClass object
            SecondClass mySecondClass = new SecondClass();
            mySecondClass.ReportName = "Device Inventory Report";
            mySecondClass.FilterMode = "Container";
            mySecondClass.Destination = "someone@somewhere.com";
            mySecondClass.Format = "PDF";
            mySecondClass.DeviceID = 42;

            // add mySecondClass to the SecondClassList
            myReportsHolder.SecondClassReportList.Add(mySecondClass);
            // add the report holder to the root object
            myReportSpec.ReportsList.Add(myReportsHolder);
            // serialize and create file
            serializer.Serialize(writer, myReportSpec); <-- Will this produce the format I am looking for?
            writer.Close();
        }
    }

这是我期待的 XML 输出:

<?xml version="1.0" encoding="utf-8"?>
<ReportSpec xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Version="4.5" Username="My Name" xmlns="ReportAutomation Test Application">
    <FirstClassReportsList>
        <FirstClass ReportName="Base Camp Report" FilterMode="Container" Destination="someone@somewhere.com" Format="PDF" >
            <AlertSource>Base Camp 1</AlertSource>
        </FirstClass>
        <FirstClass ReportName="Satellite Stations Report" FilterMode="Container" Destination="''path'on'my'network" Format="DOC" >
            <AlertSource>Satellite Station 1</AlertSource>
        </FirstClass>
    </FirstClassReportsList>
    <SecondClassReportsList ReportName="Device Inventory Report" FilterMode="Container" Destination="someone@somewhere.com" Format="PDF" >
        <SecondClass>
            <DeviceID>42</DeviceID>
        </SecondClass>
    </SecondClassReportsList>
</ReportSpec>

如果我正在创建 FirstClass 对象的实例并设置其属性,并且如果我正在创建 ReportsHolder 类的实例以将我的对象放入其中,为什么会收到"对象引用"错误? 我正在自学序列化,所以这对我来说有点不知所措。

序列化多个对象错误:对象未设置为实例

您需要先创建列表,然后再向其添加项目:

你可以在构造函数中执行此操作(这样你就不会在程序中忘记它):

public class ReportSpec{
    [System.Xml.Serialization.XmlElementAttribute("Report")]
    public List<ReportsHolder> ReportsList { get; set; }
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public double Version { get; set; }
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string Username { get; set; }
    public ReportSpec()
    {
        this.ReportsList = new List<ReportsHolder>();
    }    
}

public class ReportsHolder{
    public List<FirstClass> FirstClassReportsList { get; set; }
    public List<SecondClass> SecondClassReportList { get; set; }
    public ReportsHolder()
    {
        this.FirstClassReportsList = new List<FirstClass>();
        this.SecondClassReportList = new List<SecondClass>();
    }    
}

从现在开始,您可以将项目添加到列表中

对于您问题的第二部分:

序列化程序。Serialize(writer, myReportSpec);<--这会产生我正在寻找的格式吗?

您期望的格式是ReportsHolder类的结构,而不是ReportSpec的结构。所以你应该序列化myReportsHolder

serializer.Serialize(writer, myReportsHolder); 

但是第一个标签当然会<ReportsHolder...