[C#]使用類別中有ArrayList型別資料成員,反序列化形態轉換錯誤-System.InvalidCastException處理

因為現在工作的環境關係,需要使用到Net1.1開發,所以很多功能都沒有,其中也包含了List此泛型串列,所以在Net1.1上都是使用ArrayList在做儲存,而此時便出現了一個問題

如果在某類別定義中,包含了ArrayList成員,由於ArrayList存放的是Object型別物件,所以在做反序列化時,會出現型態轉換的問題,以下來介紹與處理。

前言

 


 

因為現在工作的環境關係,需要使用到Net1.1開發,所以很多功能都沒有,其中也包含了List<T>此泛型串列,所以在Net1.1上都是使用ArrayList在做儲存,而此時便出現了一個問題

如果在某類別定義中,包含了ArrayList成員,由於ArrayList存放的是Object型別物件,所以在做反序列化時,會出現型態轉換的問題,以下來介紹與處理。

 

類別中包含ArrayList的例子

 


 

在使用Json序列化與反序列化上,由於是把NT上的資料透過WebService傳送到較新的主機上,所以新的主機上開發環境不存在Net1.1,也因此直接使用Json.Net去做反序列化。

而在反序列化前,我要反序列化成的類別定義類似如下:

 

這是一個紀錄新增移除中,每一項安裝軟體的基本資訊,其中softwareAppProgramDetail 是一個ArrayList ,裡面的每一項資料保存的是ExecutableProgramDetail型別物件,代表了這個安裝軟體相關的各個執行檔資訊。


public class InstalledSoftwareInfo
{
    public InstalledSoftwareInfo()
    {
        softwareAppProgramDetail = new ArrayList();
    }
    private string displayName;
      

    //..Other Code

    private ArrayList softwareAppProgramDetail; //保存的是ExecutableProgramDetail型別的物件
}

 

然後因為會有很多InstalledSoftwareInfo型別物件,所以另外又用一個ArrayList保存,如下:


ArrayList installedSoftwares = new ArrayList ();

installedSoftwares .Add( installedSoftwares  ); //installedSoftwares 是InstalledSoftwareInfo型別物件,裡頭包含了許多與installedSoftwares相關的執行檔案。

 

遇到的錯誤訊息

 


 

一開始我做反序列化時,因為在WebService上的主機可以使用新的.Net,所以使用List<T>的方式取回資料。沒有想太多,很直覺得做法是`:

//轉換格式


List<installedsoftwareinfo> installedSoftwares = JsonConvert.DeserializeObject>(jsonString);

 

拿到了各個新增移除中的軟體資訊後,再來是取得各個軟體資訊中相關的執行檔案,如下:


foreach (InstalledSoftwareInfo installedSoftware in installedSoftwares){

     List<ExecutableProgramDetail> appDetails = installedSoftware.SoftwareAppProgramsDetail.Cast<ExecutableProgramDetail>().ToList();

    //… Other Code

}

 

於是在執行時,出現了以下錯誤:

Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'AgentReceiverWebServiceFormSample.AgentReceiverWS+obJson' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.

 

To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
Path ''

 

原因與處理方法

 


 

其實想一下就是知原因的問題,因為一開始在做反序列化時,轉換成InstalledSoftwareInfo類別,因為裡面是ArrayList,所以無法把那部分的內部的Json字串做一個對應的轉換為ExecutableProgramDetail,而是以String型別的方式保存下來。

 

所以如果把資料印出來會是仍以Json格式的字串顯示installedSoftware.SoftwareAppProgramsDetail的每一筆資料,因此我們處理方式應是如下:


foreach (InstalledSoftwareInfo installedSoftware in installedSoftwares){
    ArrayList array = installedSoftware.SoftwareAppProgramsDetail;
    for (int j = 0; j < array.Count; j++)
    {
         string appDetailStr = array[j].ToString();
        //對ArrayList反序列化(因為ArrayList無法解析所以裡頭是Json字串)
         ExecutableProgramDetail appDetail = JsonConvert.DeserializeObject<ExecutableProgramDetail>(appDetailStr);

       //Other code..
    }
}

 

在做一次反序列化,把SoftwareAppProgramsDetail中的每一筆Json字串做反序列化,才可以拿到ArrayList中應該要的ExecutableProgramDetail 型別資料。

 

後記

 


 

真的很少在使用ArrayList,都是用List<T>,所以便沒有注意到有這些問題,所以也是一個備忘記錄,如果剛好有遇到此狀況,此篇希望能協助到您。

 


 

文章中的敘述如有觀念不正確錯誤的部分,歡迎告知指正 謝謝 =)

另外要轉載請附上出處 感謝