Search code examples
c#.netjsonstringsorting

C# Sort JSON string keys


I'd like to convert the JSON string

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

to

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

NOTE: I'm not using the sorted version for communication (because the key order doesn't really matter), I need a sorted version to perform local tests (by comparing JSON strings).


EDIT: I4V pointed a solution that uses Json.Net, I would rather use a solution that doesn't need to include any 3rd party library (actually I'm using the built in System.Json in my application)


I posted a gist with the solution provided by I4V + some testing here. Thank you all.


Solution

  • I will use Json.Net for this

    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);
        }
    }
    

    EDIT

    A try with System.Json but I am not sure about OrderByDescending ( or 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);
        }
    }