2013-01-19 67 views
8

我想JSON字符串轉換C#排序JSON字符串鍵

"{ \"birthday\": \"1988-03-18\", \"address\": { \"state\": 24, \"city\": 8341, \"country\": 1 } }" 

"{ \"address\": { \"city\": 8341, \"country\": 1, \"state\": 24 }, \"birthday\": \"1988-03-18\" }" 

注意:我不使用通訊排序版本(因爲鍵順序沒有按真的很重要),我需要一個排序版本來執行本地測試(通過比較JSON字符串)。


編輯: I4V指出使用Json.Net,我寧願使用不需要包含任何第三方庫(其實我使用的是內置的System.Json在溶液中而我應用程序)


我張貼與由I4V +一些測試here提供的溶液中的要點。謝謝你們。

+0

嗯......雖然聽起來很誘人,但我敢肯定,更好的解決方案是對JSON進行更深入的檢查,而不是進行字符串比較。鑑於JS中屬性的枚舉不是由規範決定的,因此不應該依賴對象屬性的順序,因爲訂購json序列化的屬性確實沒有意義。 ECMA-262,第12.6.4節:枚舉屬性......的機制取決於實現。 – spender

+0

@spender我同意你的意見,JSON鍵順序是沒有意義的,字符串比較不應該用於比較大型/複雜的JSON對象。但是JSON字符串分類器可能對非常特殊的情況有用(如我的) –

回答

10

我會用Json.Net這個

string json = @"{ ""birthday"": ""1988-03-18"", ""address"": { ""state"": 24, ""city"": 8341, ""country"": 1 } }"; 
var jObj = (JObject)JsonConvert.DeserializeObject(json); 
Sort(jObj); 
string newJson = jObj.ToString(); 

void Sort(JObject jObj) 
{ 
    var props = jObj.Properties().ToList(); 
    foreach (var prop in props) 
    { 
     prop.Remove(); 
    } 

    foreach (var prop in props.OrderBy(p=>p.Name)) 
    { 
     jObj.Add(prop); 
     if(prop.Value is JObject) 
      Sort((JObject)prop.Value); 
    } 
} 

編輯

一個嘗試System.Json但我不知道OrderByDescending(或OrderBy)。

var jObj = (System.Json.JsonObject)System.Json.JsonObject.Parse(json); 
Sort2(jObj); 
var newJson = jObj.ToString(); 

void Sort2(System.Json.JsonObject jObj) 
{ 
    var props = jObj.ToList(); 
    foreach (var prop in props) 
    { 
     jObj.Remove(prop.Key); 
    } 

    foreach (var prop in props.OrderByDescending(p => p.Key)) 
    { 
     jObj.Add(prop); 
     if (prop.Value is System.Json.JsonObject) 
      Sort2((System.Json.JsonObject)prop.Value); 
    } 
} 
+0

有趣。但我正在使用內置的系統。Json在我的應用程序中,所以我寧願使用不需要第三方庫的解決方案。 –

+0

您是否想要從JObj中刪除屬性而不是屬性列表?看起來你正在從屬性列表中刪除所有項目,然後嘗試對它進行排序和枚舉。 – Despertar

+0

我編輯了我的問題與您的解決方案和我的約束 –

2

通過使用this approach you can retrieve a dynamic object with your json data

DynamicJsonConverter創建SortedDictionary代替

var d = new SortedDictionary<string, object>(dictionary); 
// TODO: code to sort inner objects 
return new DynamicJsonObject(d); 

然後你可以使用

string jsonStr = "{\"B\":\"2\",\"A\":\"1\"}"; 
JavaScriptSerializer jss = new JavaScriptSerializer(); 
jss.RegisterConverters(new JavaScriptConverter[] { new DynamicJsonConverter() }); 

dynamic json = jss.Deserialize(jsonStr, typeof(object)) as dynamic; 

string result = new JavaScriptSerializer().Serialize((json as DynamicJsonObject).Dictionary); 

result將具有預期的輸出。

+1

謝謝@BrunoLM,但是我最終使用普通的'System.Json.JsonObject'。 –

0

我知道這可能是晚了一點,但是,如果你需要數據的內部數組排序太(我只需要它):

static void Sort(JObject jObj) 
{ 
    var props = jObj.Properties().ToList(); 
    foreach (var prop in props) 
    { 
     prop.Remove(); 
    } 

    foreach (var prop in props.OrderBy(p => p.Name)) 
    { 
     jObj.Add(prop); 
     if (prop.Value is JObject) 
      Sort((JObject)prop.Value); 
     if (prop.Value is JArray) 
     { 
      Int32 iCount = prop.Value.Count(); 
      for (Int32 iIterator = 0; iIterator < iCount; iIterator++) 
       if (prop.Value[iIterator] is JObject) 
        Sort((JObject)prop.Value[iIterator]); 
     } 
    } 
} 

乾杯!