1

I have an issue ahead of me and I am not sure even how to being approaching it.

The background is that I have a "record" coming from an API in a JSON string. This string is VERY dynamic and predicting the pair keys is almost impossible. BUT in the record there is always four fields, and these are the four I want to change.

In order to update the record the entire dataset must be sent back with the values you wish to update (Sending back only the fields I want to update results in all currently set fields being wiped out)

So my plan was, pull the JSON string, leave it in string format and then parse it to find the pairs that I want to change and then give the JSON string back to the API and magic! The fields won't be wiped.

So the issue I am facing is coming up with an idea of how to parse this string, find a key value "keyvalue1" and then updating its value "keyvalue1":"Update me"

This is a sample of the string I am working with: (The valuetobeupdated 1 - 4 and areas that need to be changed)

"{\"record\":
  {\"status\":\"241\",
   \"id\":\"a0de27a2-1447-4941-a3c0-8853e5682e85\",
   \"created_by\":\"The Amazing Mongo\",
   \"project_id\":null,
   \"changeset_id\":\"eeba5ba9-8305-4cb3-ad63-6d1bbff6b626\",
   \"valuetobeupdated1\":\"some long value needs to go in here\",
   \"valuetobeupdated2\":\"more data is needed here\",
   \"form_values\":      
    {\"833b\":\"00000\",
     \"683b\":\"00000\",
     \"62b2\":\"370\",
     \"6472\":\"615\",
     \"e4fa\":\"552\",
     \"7868\":\"1\",
     \"0d48\":\"4\",
     \"1d54\":\"25\",
     \"2155\":\"200\",
     \"6435\":\"2\",
     \"f4ad\":\"33\",
     \"6c2b\":\"108\",
     \"adb5\":\"62\",
     \"e622\":\"0\",
     \"d1f0\":\"25\",
     \"8cf6\":\"0\",
     \"80ad\":\"0\",
     \"6fe4\":\"0\",
     \"a148\":\"2016-05-13\",
     \"6f55\":\"11:49\",
     \"3b7c\":{\"choice_values\":[\"2409\"],
               \"other_values\":[]},
     \"valuetobeupdated3\":{\"choice_values\":[\"More information goes in here\"],
                            \"other_values\":[]
                            },
     \"valuetobeupdated4\":{\"choice_values\":[\"more information here\"],
                            \"other_values\":[]
                           },
     \"course\":null,}}"

So my question is how do I go about starting this, I have never been great at regular expressions and am not even sure if regex can do what I want to do here. The "Some long value needs to go here" and other values can be any length.

Any advice will be appreciated.

Caz1224
  • 1,539
  • 1
  • 14
  • 37
  • 2
    Have you looked at JSON.net? That would be a better way to go than Regex: http://www.newtonsoft.com/json/help/html/readingwritingjson.htm – Ian Mercer May 13 '16 at 04:49
  • I agree. Either use the StringReader as demonstrated in @IanMercer's link above, or if it's possible, define a C# object that matches the type being passed in and deserialise into that type. You've mentioned that the data is very dynamic, so this may not be possible, but it would be my preferred approach. – Ashby May 13 '16 at 04:55
  • [this](http://stackoverflow.com/questions/22191167/convert-json-string-to-c-sharp-object-list) may be of your interest – Thangadurai May 13 '16 at 04:57
  • Is the general path invariant other than addition or removal of those hex fields? such as the name of `form_values` and `choice_values` – Xiaoy312 May 13 '16 at 05:01
  • @IanMercer Having a read of that now. Not 100% sure it will do what I want. – Caz1224 May 13 '16 at 05:04
  • @Ashby - I would love to have a nice static dataset and make a class from it, but alas the IT gods hate me. – Caz1224 May 13 '16 at 05:04
  • @Xiaoy312 - Not sure what you mean, those hex fields are actually data keys not hex values (I know its painful but its not my API) the key is pulling the record changing the fields and pushing it back up without altering the overall structure of the string. – Caz1224 May 13 '16 at 05:04
  • @Caz1224 I mean other than those hex key names can changes, is the rest of the json structure always the same? – Xiaoy312 May 13 '16 at 05:06
  • Yes, as soon as it gets to "form_values" that's when it starts getting dynamic, all the values above that always exist. But I also need to change a some values in the form_values area well, more like remove them. valuetobeupdated3 and 4 need to be deleted on the update and I was considering if I found a way to parse this well I could just remove the fields completely – Caz1224 May 13 '16 at 05:09

1 Answers1

3

Using Json.NET and dynamic :

var root = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(json);
root.record.valuetobeupdated1 = "Loonnnnnnnnnnnnnnnnnng value";
root.record.valuetobeupdated2 = "More data";
root.record.form_values.Remove("valuetobeupdated3");
root.record.form_values.Remove("valuetobeupdated4");

var output = JsonConvert.SerializeObject(root, Newtonsoft.Json.Formatting.Indented);
Console.WriteLine(output);

Output :

{
  "record": {
    "status": "241",
    "id": "a0de27a2-1447-4941-a3c0-8853e5682e85",
    "created_by": "The Amazing Mongo",
    "project_id": null,
    "changeset_id": "eeba5ba9-8305-4cb3-ad63-6d1bbff6b626",
    "valuetobeupdated1": "Loonnnnnnnnnnnnnnnnnng value",
    "valuetobeupdated2": "More data",
    "form_values": {
      "833b": "00000",
      "683b": "00000",
      "62b2": "370",
      "6472": "615",
      "e4fa": "552",
      "7868": "1",
      "0d48": "4",
      "1d54": "25",
      "2155": "200",
      "6435": "2",
      "f4ad": "33",
      "6c2b": "108",
      "adb5": "62",
      "e622": "0",
      "d1f0": "25",
      "8cf6": "0",
      "80ad": "0",
      "6fe4": "0",
      "a148": "2016-05-13",
      "6f55": "11:49",
      "3b7c": {
        "choice_values": [
          "2409"
        ],
        "other_values": []
      },
      "course": null
    }
  }
}

Full test code :

var json = @"{""record"":
  {""status"":""241"",
   ""id"":""a0de27a2-1447-4941-a3c0-8853e5682e85"",
   ""created_by"":""The Amazing Mongo"",
   ""project_id"":null,
   ""changeset_id"":""eeba5ba9-8305-4cb3-ad63-6d1bbff6b626"",
   ""valuetobeupdated1"":""some long value needs to go in here"",
   ""valuetobeupdated2"":""more data is needed here"",
   ""form_values"":      
    {""833b"":""00000"",
     ""683b"":""00000"",
     ""62b2"":""370"",
     ""6472"":""615"",
     ""e4fa"":""552"",
     ""7868"":""1"",
     ""0d48"":""4"",
     ""1d54"":""25"",
     ""2155"":""200"",
     ""6435"":""2"",
     ""f4ad"":""33"",
     ""6c2b"":""108"",
     ""adb5"":""62"",
     ""e622"":""0"",
     ""d1f0"":""25"",
     ""8cf6"":""0"",
     ""80ad"":""0"",
     ""6fe4"":""0"",
     ""a148"":""2016-05-13"",
     ""6f55"":""11:49"",
     ""3b7c"":{""choice_values"":[""2409""],
               ""other_values"":[]},
     ""valuetobeupdated3"":{""choice_values"":[""More information goes in here""],
                            ""other_values"":[]
                            },
     ""valuetobeupdated4"":{""choice_values"":[""more information here""],
                            ""other_values"":[]
                           },
     ""course"":null,}}}";

var root = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(json);
root.record.valuetobeupdated1 = "Loonnnnnnnnnnnnnnnnnng value";
root.record.valuetobeupdated2 = "More data";
root.record.form_values.Remove("valuetobeupdated3");
root.record.form_values.Remove("valuetobeupdated4");

var output = JsonConvert.SerializeObject(root, Newtonsoft.Json.Formatting.Indented);
Console.WriteLine(output);

Note: I added a } at the end of the json, otherwise it wouldn't be a valid json.

Xiaoy312
  • 14,292
  • 1
  • 32
  • 44