回答
我隨後經由反射JsonConvert.SerializeObject(key)
方法調用(其中鍵是一個IList),發現JsonSerializerInternalWriter.SerializeList被調用。它需要一個列表,並通過
for (int i = 0; i < values.Count; i++) { ...
其中值是IList的參數帶來的遍歷。
簡短的回答是......不,沒有內置的方法來設置字段的順序列在JSON字符串中。
簡短的回答,但可能過時。看看史蒂夫的回答(由詹姆斯牛頓王支持) – 2015-08-01 13:41:20
JSON格式的字段沒有順序,所以定義一個順序是沒有意義的。
{ id: 1, name: 'John' }
相當於{ name: 'John', id: 1 }
(兩者都表示嚴格相等對象實例)
這隻適用於「在線」傳輸,而不適用於另一端的消耗。一旦反序列化,基本上我並不期望命令持續存在。 – 2010-07-25 21:03:45
你在說什麼? JSON是一種允許對象序列化/反序列化的格式。在OOP的對象字段中沒有概念*順序*。 – 2010-07-25 21:04:50
@Darin - 但是在序列化中有一個命令。 「{id:1,name:'John'}」and「{name:'John',id:1}」與* strings *不同,這就是我所關心的。當然,反序列化時對象是等價的。 – 2010-07-25 21:09:21
您可以通過執行IContractResolver
或覆蓋DefaultContractResolver
的CreateProperties
方法實際控制訂單。
這裏是我的簡單實現IContractResolver
的例子字母定購屬性:
public class OrderedContractResolver : DefaultContractResolver
{
protected override System.Collections.Generic.IList<JsonProperty> CreateProperties(System.Type type, MemberSerialization memberSerialization)
{
return base.CreateProperties(type, memberSerialization).OrderBy(p => p.PropertyName).ToList();
}
}
,然後設置設置和序列化對象,而JSON字段將是按字母順序排列:
var settings = new JsonSerializerSettings()
{
ContractResolver = new OrderedContractResolver()
};
var json = JsonConvert.SerializeObject(obj, Formatting.Indented, settings);
完美地爲我工作 – michaelAngelo 2012-11-14 14:54:26
謝謝!我正在找那個! – esskar 2013-03-16 18:15:42
這非常有用(+1),但有一點需要注意:它出現的字典序列化不會使用此CreateProperties自定義。他們序列化好,但不會最終排序。我假設有一種不同的方式來定製字典的序列化,但我還沒有找到它。 – solublefish 2015-03-06 19:46:12
以下遞歸方法使用反射來對現有的JObject
實例上的內部令牌列表進行排序,而不是創建一個br和新的排序對象圖。此代碼依賴於內部的Json.NET實現細節,不應在生產中使用。
void SortProperties(JToken token)
{
var obj = token as JObject;
if (obj != null)
{
var props = typeof (JObject)
.GetField("_properties",
BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(obj);
var items = typeof (Collection<JToken>)
.GetField("items", BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(props);
ArrayList.Adapter((IList) items)
.Sort(new ComparisonComparer(
(x, y) =>
{
var xProp = x as JProperty;
var yProp = y as JProperty;
return xProp != null && yProp != null
? string.Compare(xProp.Name, yProp.Name)
: 0;
}));
}
foreach (var child in token.Children())
{
SortProperties(child);
}
}
支持的方法是使用上要設置訂單的類屬性的屬性JsonProperty
。 Read the JsonPropertyAttribute order documentation for more information。
通過JsonProperty
和Order
值,序列化程序將處理其餘的。
[JsonProperty(Order = 1)]
這是非常相似的
DataMember(Order = 1)
的
System.Runtime.Serialization
天
。
使用'JsonPropertyAttribute'的'Order'屬性可以控制字段序列化/反序列化的順序。但是,如果您在所有其他屬性上設置的訂單大於1,則僅將訂單設置爲1。默認情況下,沒有訂單設置的任何屬性將被賦予-1的順序。所以你必須給所有序列化的屬性和順序,或者將你的第一項設置爲-2。 – 2014-02-25 11:23:27
這個解決方案對我來說非常合適。^5 – 2015-07-16 21:58:33
它適用於序列化,但是在反序列化中沒有考慮該順序。根據文檔,order屬性用於序列化和反序列化。有沒有解決方法? – cangosta 2015-12-21 18:46:36
在我的情況下,Mattias的答案沒有奏效。 CreateProperties
方法從未被調用過。
在對Newtonsoft.Json
內部進行了一些調試之後,我想出了另一種解決方案。
public class JsonUtility
{
public static string NormalizeJsonString(string json)
{
// Parse json string into JObject.
var parsedObject = JObject.Parse(json);
// Sort properties of JObject.
var normalizedObject = SortPropertiesAlphabetically(parsedObject);
// Serialize JObject .
return JsonConvert.SerializeObject(normalizedObject);
}
private static JObject SortPropertiesAlphabetically(JObject original)
{
var result = new JObject();
foreach (var property in original.Properties().ToList().OrderBy(p => p.Name))
{
var value = property.Value as JObject;
if (value != null)
{
value = SortPropertiesAlphabetically(value);
result.Add(property.Name, value);
}
else
{
result.Add(property.Name, property.Value);
}
}
return result;
}
}
這是使用字典時所需的修復方法。 – noocyte 2015-06-03 08:39:38
實際上,因爲我的目標已經是一個JObject,我用以下解決方案:
public class SortedJObject : JObject
{
public SortedJObject(JObject other)
{
var pairs = new List<KeyValuePair<string, JToken>>();
foreach (var pair in other)
{
pairs.Add(pair);
}
pairs.OrderBy(p => p.Key).ForEach(pair => this[pair.Key] = pair.Value);
}
}
,然後用它是這樣的:
string serializedObj = JsonConvert.SerializeObject(new SortedJObject(dataObject));
在我的情況niaher的解決方案做了不工作,因爲它沒有處理數組中的對象。
基於他的解決辦法,這是我想出了
public static class JsonUtility
{
public static string NormalizeJsonString(string json)
{
JToken parsed = JToken.Parse(json);
JToken normalized = NormalizeToken(parsed);
return JsonConvert.SerializeObject(normalized);
}
private static JToken NormalizeToken(JToken token)
{
JObject o;
JArray array;
if ((o = token as JObject) != null)
{
List<JProperty> orderedProperties = new List<JProperty>(o.Properties());
orderedProperties.Sort(delegate(JProperty x, JProperty y) { return x.Name.CompareTo(y.Name); });
JObject normalized = new JObject();
foreach (JProperty property in orderedProperties)
{
normalized.Add(property.Name, NormalizeToken(property.Value));
}
return normalized;
}
else if ((array = token as JArray) != null)
{
for (int i = 0; i < array.Count; i++)
{
array[i] = NormalizeToken(array[i]);
}
return array;
}
else
{
return token;
}
}
}
如果你控制(即寫入)類,把屬性按字母順序排列,他們將按照字母順序序列化時JsonConvert.SerializeObject()
被調用。
查理指出,可以一定程度上受到的類本身訂貨屬性控制JSON屬性的排序。不幸的是,這種方法不適用於從基類繼承的屬性。基類屬性將按照它們在代碼中的佈局進行排序,但會顯示在基類屬性之前。
而且任何人都知道爲什麼,你可能想按字母順序排列JSON性能,它是一個整體更容易與原始JSON文件的工作,特別是對類有很多的屬性,如果他們是有序的。
- 1. 序列化時的順序字段
- 2. 反序列化使用json.net
- 3. 使用json.Net序列化ExpandoObject
- 4. 用Json.NET序列化
- 5. 使用JSON.Net反序列化爲所有字段返回null(VB)
- 6. 使用Json.NET序列化Vector2的數組
- 7. Json.NET:序列化/反序列化陣列
- 8. 序列化/反序列化的字節數組中JSON.NET
- 9. 序列化/反序列化JSON.NET的對象字典
- 10. JSON.NET反序列化
- 11. JSON.NET序列化的ProcessStartInfo
- 12. 用json.net反序列化JSON
- 13. 使用JSON.NET反序列化和序列化字典<字符串,對象>
- 14. 使用json.net c反序列化json#
- 15. 使用json.net序列化爲對象
- 16. 定製反序列化使用Json.NET
- 17. 使用Json.NET反序列化枚舉值
- 18. C#以JSON序列化使用JSON.Net
- 19. 序列化使用ContractResolver和JsonConverter(JSON.NET)
- 20. 使用Json.Net反序列化Json對象
- 21. 使用JSON.Net序列化外語
- 22. 反序列化使用JSON.Net解串器
- 23. 反序列化JSON使用JSON.NET
- 24. 由JSON.NET序列化時,屬性順序會搞亂
- 25. fasterxml JSON序列化:如何設置某個字段的順序?
- 26. 基於字段順序的Java對象序列化器
- 27. 使用Json.net和C#反序列化嵌套的json字符串?
- 28. 使用json.net進行反序列化時,數組順序是否保留?
- 29. Json.Net反序列化提領
- 30. 反序列化JSON C#Json.net
只是出於好奇,爲什麼你會在意嗎? – 2012-07-03 10:41:44
我想他可能會首先顯示ID字段(或類似字段),然後是所有其他字段。對於最終用戶而言,這比對以A..I – michaelAngelo 2012-11-14 14:53:54
開頭的字段之後的字符進行查找更友好.JSON屬性被定義爲無序。我認爲在序列化過程中強制執行某個OUTPUT命令是絕對沒問題的(也許是爲了目擊JSON),但是在反序列化的任何特定順序上創建DEPENDENCY將是一個錯誤的決定。 – DaBlick 2015-06-30 12:58:28