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

时间:2016-07-06 15:00:31

标签: c# xml serialization

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

这是我的序列化代码:

[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类的实例来放置我的对象,为什么我得到“对象引用”错误?我一直在进行自我教学序列化,所以这对我来说有点压倒性。

1 个答案:

答案 0 :(得分:0)

您需要在向其添加项目之前创建列表:

你可以在构造函数中这样做(这样你就不会忘记它在程序中):

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>();
    }    
}

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

问题的第二部分:

  

serializer.Serialize(writer,myReportSpec); &lt; - 这会产生我想要的格式吗?

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

serializer.Serialize(writer, myReportsHolder); 

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