2

次のコードは正常に動作します

List<string> alist = new List<string>() { "1", "2", "3" };
string serialisedList= (new JavaScriptSerializer()).Serialize( alist );
List<int> deserialisedList= JsonConvert.DeserializeObject<List<int>>( serialisedList);

上記の例の serialisedList の値は、"[\"1\",\"2\",\"3\"]" です。

次に、チェックされた CheckboxList コントロール値の配列であるプロパティを持つ JavaScript オブジェクトを作成します。このオブジェクトを JSON に変換すると、キーと値のペアは次のようになります。

{
   "SomeProp": "[\"1\",\"2\",\"3\"]"
}

したがって、基本的にここの値は上記のものとまったく同じです。ただし、これを C# オブジェクトに逆シリアル化しようとすると、次のようになります。

public class ServerObject
{
   public List<int> SomeProp { get; set; }
}

ServerObject deserialisedObj = JsonConvert.DeserializeObject<ServerObject>( jsonString );

エラーが発生します:

Error converting value "["1","2","3"]" to type 'System.Collections.Generic.List`1[System.Int32]'. Path 'SomeProp'

直接型に直接変換できるのに、同じ値をオブジェクト プロパティに逆シリアル化できないのはなぜですか?

4

2 に答える 2

2

STRINGS のリストをシリアライズしています。魔法のようにINTSのリストになるとどう思いますか? はい、JSON は一般に型がなく、キーと値のペアで機能しますが、値に関しては、最も基本的な形式情報が保持されます。JSON では、文字列と数値 (および配列/リストとマップ/オブジェクト) が区別されます。出力された JSON を見てください。

{
   "SomeProp": ["1","2","3"]
}

明らかに、これは文字列の配列です。

JSON では、数値の配列は次のようになります。

{
   "SomeProp": [1,2,3]
}

したがって、最初に次のようにシリアル化する必要があります。

List<string> alist = new List<string>() { "1", "2", "3" };

List<int> list2 = alist.Select(str => int.Parse(str)).ToList();
string serialisedList= (new JavaScriptSerializer()).Serialize( list2 );

List<int> deserialisedList= JsonConvert.DeserializeObject<List<int>>( serialisedList);

そしてあなたの質問に関して:

同じ値をオブジェクト プロパティに逆シリアル化できないのはなぜですか (..)

基になる値の型が一致しないためです。左側には文字列、右側には整数があります。デシリアライザーがそれを行う方法を知るにはどうすればよいですか? 文字列が基数 10 の整数ではなく、基数 16 の整数であり、幸運にも文字 AF を使用しなかった場合はどうなるでしょうか?

質問の2番目の部分については

(..) 直接型に直接入力できますか?

いいえ、できません。値の型が一致しない場合は、適切なラウンドトリップ ライブラリがスローされます。JSON処理ライブラリでJSON値「blargh」をINTフィールド/プロパティに割り当てることができる場合、まあ、私にとっては、それは機能ではなくバグです:)

于 2013-02-25T09:54:59.390 に答える
0

JavaScriptSerializer を使用して逆シリアル化すると、動作するはずです。

List<int> deserialisedList = new JavaScriptSerializer().Deserialize<List<int>>(serialisedList);
于 2013-02-25T10:01:36.387 に答える