3

私は次のものを持っています:

public class BaseEntity<T> where T: class
{
    public OperationStatus OperationStatus { set; get; }
    public List<T> List { set; get; }

    protected internal BaseEntity()
    {
        if (OperationStatus == null)
        {
            OperationStatus = new OperationStatus();
            OperationStatus.IsSuccess = true;
        }

        this.List = new List<T>();
    }

    internal BaseEntity(IEnumerable<T> list)
    {
        if (OperationStatus == null)
        {
            OperationStatus = new OperationStatus();
            OperationStatus.IsSuccess = true;
        }

        this.List = new List<T>();
        foreach (T k in list)
        {
            this.List.Add(k);
        }
    }

}

public class KeyValuePair
{
    public string key;
    public string value;
}

public class KeyValuePairList : BaseEntity<KeyValuePair>
{
    public KeyValuePairList() { }
    public KeyValuePairList(IEnumerable<KeyValuePair> list)
        : base(list) { }
}

// Multiple other classes like KeyValuePair but all have the
// same behavior so they have been derived from BaseEntity

今私のコードでは、JSON文字列をKeyValuePairリストのインスタンスにマップしようとしていますが、現在は次のように実行しています。

result = 
@"{
    \"d\": {
        \"OperationStatus\": {
            \"IsSuccess\": true,
            \"ErrorMessage\": null,
            \"ErrorCode\": null,
            \"InnerException\": null
        },
        \"List\": [{
            \"key\": \"Key1\",
            "\value\": \"Value1\"
        }, {
            \"key\": \"Key2\",
            \"value\": \"Value2\"
        }]
    }
}"

試行#1

JavaScriptSerializer serializer = new JavaScriptSerializer();
KeyValuePairList output = serializer.Deserialize<KeyValuePairList>(result);

ただし、のコンストラクターがKeyValuePairList引数を指定して呼び出されていないため、これは機能しません。そのコンストラクターを削除すると、JSONシリアル化がエラーで失敗しますNo parameterless constructor found。呼び出しでテンプレートとしてKeyValuePairList使用するように指示するにはどうすればよいですか?KeyValuePairまたは、この目的のためにJSONシリアライザーをどのように適応させることができますか?

試行#2

私も次のように試しJSON.netました:

var oo = JsonConvert.DeserializeObject<KeyValuePairList>(result);

これを機能させる方法について何か提案はありますか?

4

2 に答える 2

2

実際、解決策は私が思っていたよりも簡単です。問題は、サーバーがルートノードでJSON文字列を返していることdです。このため、ルートノードをどう処理するかがわからないため、逆シリアル化は失敗しますd。これは次のように解決できます。

手順1:着信JSON文字列をラップするクラスJSONWrapperを追加します。

public class JSONWrapper<T> where T:class
{
    public T d {set; get;}
}

ステップ2:代わりにこの新しいクラスを使用して逆シリアル化する

JavaScriptSerializer serializer = new JavaScriptSerializer();
var oo = serializer.Deserialize<JsonWrapper<KeyValuePairList>>(result);

私のロジック全体とはるかに一致しているので、大きな変更を加える必要はありません。貴重な時間を割いてくれた他のみんなに感謝します。

于 2012-07-09T20:06:48.517 に答える
0

T[]代わりに試してくださいList<T>

次の2つのプロパティが必要です。

public T[] Items{
    get{
        return ItemList.ToArray();
    }
    set{
        ItemList.Clear();
        ItemList.AddRange(value);
    }
}

[ScriptIgnore]
public List<T> ItemList {get;set;}

配列としてのアイテムはJSONでシリアル化され、他の操作にItemListを使用できます。

于 2012-07-09T19:20:48.043 に答える