2012-05-04 11 views
1

次のようにJSONを逆シリアル化しようとします(93817や935812などの数値はサーバーから動的に生成されます)。ハードコーディングすることはできません):ここでJSONを逆シリアル化しようとするとInvalidCastExceptionが発生する

{ "status":"1",    
"list":{  
"93817":{   "item_id":"93817",   
        "url":"http://url.com",   
        "title":"Page Title",   
        "time_updated":"1245626956",     
        "time_added":"1245626956",     
        "tags":"comma,seperated,list",   
        "state":"0"      
      },  
"935812":{   "item_id":"935812",   
        "url":"http://google.com",   
        "title":"Google",   
        "time_updated":"1245626956",  
        "time_added":"1245626956",  
        "tags":"comma,seperated,list",   
        "state":"1"      
    } }}  

は、逆シリアル化のためのコードです:

responseGetList = e.Result.ToString(); //responseGetList is the JSON string 

MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(responseGetList)); 

DataContractJsonSerializer serializer = 
    new DataContractJsonSerializer(typeof(List<ResponseItem>)); 

ResponseItem li = (ResponseItem)serializer.ReadObject(ms); 

そして次はResponseItemクラスです:

namespace whatever 
{ 
    [DataContract] 
    public class ResponseItem 
    { 
     [DataMember(Name = "status")] 
     string status; 
     public string Status 
     { 
      get { return status; } 
      set { status = value; } 
     } 
     [DataMember(Name = "list")] 
     List<ListItem> list; 
     private List<ListItem> List 
     { 
      get { return list; } 
      set { list = value; } 
     } 
    } 
    public class ListItem 
    { 
     [DataMember] 
     List<Article> listArticle; 
     public List<Article> ListArticle 
     { 
      get { return listArticle; } 
      set { listArticle = value; } 
     } 
    } 
} 

public class Article 
{ 
    [DataMember(Name = "item_id")] 
    string item_id; 
    public string Item_id 
    { 
     get { return item_id; } 
     set { item_id = value; } 
    } 
    [DataMember(Name = "url")] 
    string url; 
    public string Url 
    { 
     get { return url; } 
     set { url = value; } 
    } 
    [DataMember(Name = "title")] 
    string title; 
    public string Title 
    { 
     get { return title; } 
     set { title = value; } 
    } 
    [DataMember(Name = "time_updated")] 
    string time_updated; 
    public string Time_updated 
    { 
     get { return time_updated; } 
     set { time_updated = value; } 
    } 
    [DataMember(Name = "time_added")] 
    string time_added; 
    public string Time_added 
    { 
     get { return time_added; } 
     set { time_added = value; } 
    } 
    [DataMember(Name = "tags")] 
    string tags; 
    public string Tags 
    { 
     get { return tags; } 
     set { tags = value; } 
    } 
    [DataMember(Name = "state")] 
    string state; 
    public string State 
    { 
     get { return state; } 
     set { state = value; } 
    } 
} 

私は1にInvalidCastExceptionが取得ataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(List<ResponseItem>));、それはJSONオブジェクトマッピングの問題だと思います。誰も私を助けることができますか?

+0

JSONはJSONLintはどちらか、そうは思いませんvalid--見ていないこと辞書を使用すると、キーの解像度です。 – Robaticus

+0

編集され、JSONLint – yorkzhang

答えて

0

RILの#のソースコードを読み取ることによって、問題を修正しました(http://rilsharp.codeplex.com/ ... NewtonSoftは&は、プロジェクトへの参照を追加することを忘れないでください.dllをダウンロードしてください)。 問題は主にマッピングの問題です。JSONをデシリアライズするJson.netを使用して次に

[DataContract] 
public class ResponseItem 
{ 
    [DataMember(Name = "status")] 
    public ListStatus Status { get; set; } 

    [DataMember(Name = "since")] 
    public double Since { get; set; } 

    [DataMember(Name = "list")] 
    public Dictionary<string, RilListItem> items { get; set; } 

    public DateTime SinceDate 
    { 
     get 
     { 
      return UnixTime.ToDateTime(Since); 
     } 
    } 

ResponseItem ri = new ResponseItem(); 
    ri = JsonConvert.DeserializeObject<ResponseItem>(responseGetList); 
0

オブジェクトをデシリアライズするためにJson.NETに切り替えてみてください。エラーが起こりにくく、壊れにくいです(そして、それはオープンソースで、電話でも動作します)>

+0

Tried Json.NETで動作しますが、クラスのマッピングに失敗しました。私は "93817"や "935812"のような数字を扱う方法を知らない。彼らは動的に生成されるので、クラス名にハードコードすることはできない。これを処理するためのアイデアはありますか? – yorkzhang

+0

JSON.NETのLINQベースのコードを使用します。これは、(それを直列化するためのクラスを作成する代わりに)それを歩きながらそれを解析することができます。取得している数値はおそらくインスタンス番号なので、それを使用するとスキップ/無視できます。 –

0

リストの最初の項目が間違っています。 JSONには「93817」と「935812」と表示されますが、これらはアイテムのプロパティではありません。 JSONの最初の部分はプロパティ名でなければなりません。 ListのプロパティーがResponseItemに対応しているため、「リスト」は正しく機能しています。それらの番号を "listArticle"に変更します。私はまた、JSON.NetのためのShawn Wildermuthの提案の2番目です。

サーバーで生成されるJSONは、逆シリアル化と同じ方法でシリアル化する必要があります(つまり、(デシリアライズするのに同じフレームワークを使用する)。手でJSONを生成している場合は、JSONを生成しないでください。あなたは必要以上に多くの問題を抱えています。

あなたがオブジェクトをシリアル化した場合、あなたは以下を持っている必要があります。

{ "status":"1", 
    "list":{ 
     "listArticle":{ 
      "item_id":"93817",   
      "url":"http://url.com",   
      "title":"Page Title",   
      "time_updated":"1245626956",     
      "time_added":"1245626956",     
      "tags":"comma,seperated,list",   
      "state":"0"      
     }, 
     "listArticle":{ 
      "item_id":"935812",   
      "url":"http://google.com",   
      "title":"Google",   
      "time_updated":"1245626956",  
      "time_added":"1245626956",  
      "tags":"comma,seperated,list",   
      "state":"1" 
     } 
    } 
} 
+0

私はあなたのコメントを理解してそれをマップすることができませんでした。 「93817」と「935812」はどうすればいいですか?それらは動的に生成されるので、クラス名にハードコードすることはできません。これを処理するためのアイデアはありますか? – yorkzhang

+0

私の更新された返信 –

+0

を参照してください。辞書タイプを使用すると、問題は解決します。詳細は自分の返信を参照してください。とにかくありがとう。 – yorkzhang

2

はJSONにNewtonSoftのLINQを使用してみてください、それは仕方クリーナー方法シリアライズ/ JSON文字列を解除する

ClassName class= new ClassName(); 
objectname = JsonConvert.DeserializeObject<ClassName>(responseGetList); 

使用Json2Cです#あなたがオブジェクトに直にデシリアライズできるようにする必要があるClassNameを作成するには#

オブジェクトを使用できます。例えば、あなたのコードを持つ:結果のいずれかの時に呼び出す __

object.list(93817(C#は、単に数字を持つメソッドを許可していないので、あなたが、JsonPropertyでこれをキャストする必要があります))。 item_id = 93817

クリーナー:あなたはより多くの質問がある場合だけで、コメントに

EDITを追加し、

幸運をobject.list.thenameyougavethemethod.item_id:私は、JSON文字列を解析され、特定のJSONにJsonPropertiesを追加しました文字列; だけ

public class id93817 
{ 
    public string item_id { get; set; } 
    public string url { get; set; } 
    public string title { get; set; } 
    public string time_updated { get; set; } 
    public string time_added { get; set; } 
    public string tags { get; set; } 
    public string state { get; set; } 
} 

public class id935812 
{ 
    public string item_id { get; set; } 
    public string url { get; set; } 
    public string title { get; set; } 
    public string time_updated { get; set; } 
    public string time_added { get; set; } 
    public string tags { get; set; } 
    public string state { get; set; } 
} 

public class List 
{ 
    [JsonProperty("93817")] 
    public id93817 { get; set; } 
    [JsonProperty("935812")] 
    public id935812 { get; set; } 
} 

public class RootObject 
{ 
    public string status { get; set; } 
    public List list { get; set; } 
} 
+0

あなたの答えをありがとう。私はJson2Cについてはよく分かりませんが、 "http://json2csharp.com/"を試しました。あなたはこれを意味しますか?それは "93817"のような各数字をクラスに変換しますが、私は明らかにそれほど多くのクラスを持つことはできません。これのための任意の決議? – yorkzhang

+0

C#はCsharpなので、正しいサイトであり、あるクラスを作成し、他のパブリッククラスを完全に入れていると、これはあなたのPC /プログラムを遅くするとは思わない...他のセグメントと比較して2倍コードの他のすべてのクラスを含むクラスにデシリアライズすると、Json Stringを含むすべてのパラメータを持つオブジェクトが生成されます。 数値のみのパラメータがC#のクラスではありませんので、_invalid_95783などと呼ばれます。それらの名前をあなたの好みの名前に変更し、[JsonProperty]タグを追加します – NoxBene

+0

例:[JsonProperty( "93817")] public string item93817 {get;セット; } – NoxBene

関連する問題