2017-01-03 13 views
1

JSONをキー/値のない通常の形式にシリアル化しようとしていますが、残念ながらJSONファイルにキーと値の文字列が追加されます。ここ は私のポストメソッドです:SortedListをオブジェクト配列にシリアル化してキー/値を削除する

[TestMethod] 
public void PostTest() 
{ 
    var request = new HttpRequestMessage(); 
    request.Headers.Add("X-My-Header", "success"); 

    MyCaseRequest data = new MyCaseRequest() 
    { 
     Name = "TestAgre", 
     ExpirationDateTime = "2016-07-14T00:00:00.000Z", 
     Signatories = new List<SignatoryRequest> 
     { 
      new MyRequest() { Type = MyType.Comp, Id = "11111" }, 
      new MyRequest() { Type = MyType.Per, Id = "2222" } 
     }, 
     Documents = new SortedList<string, ThingsRequest>() 
     { 
      {"0" , new ThingsRequest() { Name = "Test", Description = "Short description about", Length = 4523 }}, 
      {"1" , new ThingsRequest() { Name = "Test1", Description = "short description about", Length = 56986 }} 
     } 
    }; 

    JsonSerializerSettings settings = new JsonSerializerSettings(); 
    settings.ContractResolver = new DictionaryAsArrayResolver(); 

    settings.Formatting = Formatting.Indented; 
    string json = JsonConvert.SerializeObject(data, settings); 

    var statusCode = sendJsonDemo.SendJsonDemo(json); 
} 

、ここでは、オブジェクト配列にソートされた辞書をシリアライズ私のクラスである:

class DictionaryAsArrayResolver : DefaultContractResolver 
{ 
    protected override JsonContract CreateContract(Type objectType) 
    { 
     if (objectType.GetInterfaces().Any(i => i == typeof(IDictionary) || 
       (i.IsGenericType && 
       i.GetGenericTypeDefinition() == typeof(IDictionary<,>)))) 
     { 
      return base.CreateArrayContract(objectType); 
     } 

     return base.CreateContract(objectType); 
    } 
} 

、ここでは私の出力です:

{ 
    "Name": "TestAgreement", 
    "ExpirationDateTime": "2016-07-14T00:00:00.000Z", 
    "Signatories": [ 
    { 
     "Type": "Comp", 
     "Id": "11111" 
    }, 
    { 
     "Type": "Per", 
     "Id": "2222" 
    } 
    ], 
    "Documents": [ 
    { 
     "Key": "0", 
     "Value": { 
     "Name": "Test", 
     "Description": "Short description about", 
     "Length": 4523 
     } 
    }, 
    { 
     "Key": "1", 
     "Value": { 
     "Name": "Test1", 
     "Description": "short description about", 
     "Length": 56986 
     } 
    } 
    ], 
    "Metadata": [] 
} 
+0

が本当にASP.NET固有ではないので、あなたが問題を再現できるようにする[mcve]コンソールアプリを提供できるのであれば、最高です。次に、あなたが*得ている出力を表示しました。これは 'SortedList'がキーでソートされたキー/値マップであるため意味があります。 JSONの配列になると思っていましたか?もしそうなら、 'SortedList <,>'の代わりに 'List <>'を使うべきです。 –

答えて

1

あなたはドキュメントプロパティをIEnumerable<ThingsRequest>に変更して、キー/値を持たないようにする必要があります。

SortedListを入力として使用している場合は、IEnumerable<ThingsRequest>(まだ発注済み):Documents.Valuesのように入力できます。

+0

さて、私は試しましたが、残念ながらうまくいきませんでした。IEnumerableにはJSONファイルのキーと値の文字列がありました。 – BinaryTie

+0

私は自分自身のプロジェクトでそれを使用しており、これにはキー値はありません。 'Documentsをシリアル化してもよろしいですか?あなたのオーダーされたリストの代わりにそのようなものか? – Floc

0

あなたの質問に私たちを見せなかったので、あなたが期待しているJSONがわかりません。あなたは、 "キー/値のない通常のフォーマット"がほしいと言っていますが、それはやや曖昧です。 SortedList<K, V>IDictionary<K, V>を実装し、辞書のための「通常」のシリアル化形式は次のようである:あなたのコードで

{ 
    "Documents": { 
    "0": { 
     "Name": "Test", 
     "Description": "Short description about", 
     "Length": 4523 
    }, 
    "1": { 
     "Name": "Test1", 
     "Description": "short description about", 
     "Length": 56986 
    } 
    } 
} 

、あなたがJsonArrayContractにすべての辞書のための契約を変更するには、カスタムリゾルバを使用しています。これは、Json.NetにSortedListをキーと値のペアの配列としてシリアル化するように指示します。これは、出力でKeyとValueのプロパティを取得する理由です。 「通常の」出力が必要な場合は、リゾルバを使用して契約を変更しないでください。

しかし、私はあなたが本当に探していることはあなたのような項目の単なる配列は、通常のList<T>になるだろうであることを疑い

{ 
    "Documents": [ 
    { 
     "Name": "Test", 
     "Description": "Short description about", 
     "Length": 4523 
    }, 
    { 
     "Name": "Test1", 
     "Description": "short description about", 
     "Length": 56986 
    } 
    ] 
} 

もしそうなら、あなたはカスタムを使用することができますJsonConverterこの出力を得るためにリゾルバの代わりに。

class DictionaryToValuesArrayConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return typeof(IDictionary).IsAssignableFrom(objectType); 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     IDictionary dict = (IDictionary)value; 
     JArray array = JArray.FromObject(dict.Values); 
     array.WriteTo(writer); 
    } 

    public override bool CanRead 
    { 
     get { return false; } 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 
} 

注:このコンバータは唯一のデシリアライズ、シリアライズないハンドルここでは、コンバータのために必要となるコードがあります。完全なラウンドトリップを行う必要がある場合は、ReadJsonも実装する必要がありますが、これはこの回答の対象外です。

JsonSerializerSettings settings = new JsonSerializerSettings(); 
settings.Converters.Add(new DictionaryToValuesArrayConverter()); 
string json = JsonConvert.SerializeObject(data, settings); 

デモフィドル:

JsonSerializerSettingsConvertersコレクションに追加、コンバーターを使用するには、それはこのようになりますhttps://dotnetfiddle.net/HFeXLC

関連する問題