2016-07-06 3 views
0

アプリケーション用の再利用可能なシリアライザ/デシリアライザを作成しようとしていますが、 "オブジェクト参照がオブジェクトのインスタンスに設定されていません"なぜか分からない。ここで複数のオブジェクトをシリアル化するエラー:オブジェクトがインスタンスに設定されていません

は私のシリアライザコードです:私は私のXMLファイルを作成しようとするのはここ

[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 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="[email protected]" 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="[email protected]" Format="PDF" > 
     <SecondClass> 
      <DeviceID>42</DeviceID> 
     </SecondClass> 
    </SecondClassReportsList> 
</ReportSpec> 
を:ここで

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 = "[email protected]"; 
      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 = "[email protected]"; 
      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出力であります

FirstClassオブジェクトのインスタンスを作成してそのプロパティを設定していて、インスタンスを作成している場合はReportsHolderクラスを使用してオブジェクトを配置すると、なぜ「オブジェクト参照」エラーが発生しますか?私は一緒に行くように私は直列化を自己教えているので、これは私のために少し圧倒的です。

+1

'ReportsHolder'は明らかにそれが必要としてFirstClassReportsList''のインスタンスを作成していないになります。 – Plutonix

+0

[NullReferenceExceptionとは何か、それを修正する方法は?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) ) – Plutonix

答えて

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

SEに

あなたの質問の指揮一部:

serializer.Serialize(writer, myReportSpec); <-- Will this produce the format I am looking for?

あなたの予想フォーマットはReportSpecのないことReportsHolderクラスの構造です。だから、myReportsHolder

serializer.Serialize(writer, myReportsHolder); 

をシリアル化する必要があるが、その後最初のタグには、当然のことながら<ReportsHolder...

+0

私の質問の最初の部分に関しては:ありがとう!私は、それがしばしば見落とされて、頭痛の原因となる小さなものであることがわかります。これは確かにその例です。 2番目の部分については、 'myReportsHolderを直列化するとルートオブジェクトmyReportSpecが欠落するので、必要なものを生成するためにmyReportSpecをシリアル化する必要があります。 – Kulstad

+0

コードから取得するXMLは、予想される形式と異なるはずです。ノードもあるはずですか、間違っていますか? –

+1

あなたは正しいです。出力構造はReportSpec - > Report - > ReportListになりました(少し追加した後、Filters - > FilterNameが続きます)。ここで、どのように属性をReportListからReportに移動し、Reportのフィルタを作成し、ReportListを完全に削除するかを理解する必要がありますが、これは別の質問の別のトピックです。 – Kulstad

関連する問題