2017-01-03 54 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數組嗎?如果是這樣,你應該使用'List <>'而不是'SortedList <,>'。 –

回答

1

你必須將Documents屬性更改爲IEnumerable<ThingsRequest>,以便它不具有鍵/值。

如果你有一個SortedList作爲輸入,你可以這樣做得到它作爲一個簡單的IEnumerable<ThingsRequest>(但仍然有序):Documents.Values

+0

嗯,我已經嘗試過了,但不幸的是它沒有工作,IEnumerable中有JSON文件中的鍵和值字符串。 – BinaryTie

+0

我在自己的項目中使用它,並且沒有關鍵值。你確定要序列化文檔嗎?價值「或類似的東西,而不是你的OrderedList? – 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,這超出了本答案的範圍。

要使用轉換器,將其添加到Converters集合中的JsonSerializerSettings

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

演示小提琴:https://dotnetfiddle.net/HFeXLC

相關問題