Here are a couple of Json.NET functions which I wrote to assist in working with Json operations in C#:
public class JsonHelpers { public static string MergeJsonWithStoredField(string existingJson, JProperty newJson) { if (newJson == null) throw new ArgumentNullException("newJson"); JObject jObject; if (string.IsNullOrWhiteSpace(existingJson)) { jObject = new JObject(newJson); } else { jObject = JObject.Parse(existingJson.Trim()); jObject.Add(newJson); } return jObject.ToString(Formatting.None); } public static IEnumerable<JProperty> CreateJsonPropertiesFromObject(Object objectToJsonify) { if (objectToJsonify == null) throw new ArgumentNullException("objectToJsonify"); ICollection<JProperty> properties = new List<JProperty>(); foreach (var propertyInfo in objectToJsonify.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)) { properties.Add(new JProperty(propertyInfo.Name, propertyInfo.GetValue(objectToJsonify))); } return properties; } public static string AddObjectToJsonArray(string jsonAsString, string keyOfArray, Object objectToJsonify) { JObject existingStoredJsonObject; JArray jArray; // convert object to a json object var newJsonObject = new JObject(CreateJsonPropertiesFromObject(objectToJsonify)); // if the existing stored string is null or emptiness, just create it and return. if (string.IsNullOrWhiteSpace(jsonAsString)) { existingStoredJsonObject = new JObject(); jArray = new JArray(newJsonObject); existingStoredJsonObject.Add(JsonPropertyKeys.PostEventMaterialsWereAccessed, jArray); return existingStoredJsonObject.ToString(Formatting.None); } // ************* if we got here, we need to now process the existing stored json as an input ************* existingStoredJsonObject = JObject.Parse(jsonAsString); // 1st, see if valid json is stored at all if (!ReferenceEquals(null, existingStoredJsonObject)) { JToken jToken; // 2nd, see if the array which we are augmenting already exists if (existingStoredJsonObject.TryGetValue(keyOfArray, StringComparison.OrdinalIgnoreCase, out jToken)) { jArray = jToken.Value<JArray>(); jArray.AddFirst(newJsonObject); // add so most recent is at beginning of the array return existingStoredJsonObject.ToString(Formatting.None); } // if the array does not exist in the existing json, just create it jArray = new JArray(newJsonObject); existingStoredJsonObject.Add(keyOfArray, jArray); return existingStoredJsonObject.ToString(Formatting.None); } return jsonAsString; } public static JObject CreateJsonObjectFromDictionary(IDictionary<string, string> dataForJson) { var outObject = new JObject(); foreach (var keyValuePair in dataForJson) { outObject.Add(keyValuePair.Key, keyValuePair.Value); } return outObject; } }
The methods came in handy as I was storing json in a database field of type nvarchar. I needed to be able to update the json, add new keys/values and augment existing arrays.
Here’s a few usage examples:
- Adds a new property to an existing Json object:
- Converts a C# object to a JObject and adds it as a Json object to a Javascript array.
public static AugmentOrderHistory(SomeViewModel viewModel, bool? createdByImpersonatedClaim) { ... JProperty createdByImpersonatedUserMsg = new JProperty( JsonPropertyKeys.OrderCreatedByImpersonatedUserKey, createdByImpersonatedClaim.Value ); newOrder.AdminComments = JsonHelpers.MergeJsonWithStoredField( newOrder.AdminComments, createdByImpersonatedUserMsg ); ... }
public static AugmentOrderHistoryWithObject(...) { ... var fieldsToComments = new PostEventMaterialsWereAccessed { DateAdded = TtsConfig.UtcNowAsCts, Code = identifyModel.OnDemandCode, UserEmail = identifyModel.Email, UserName = identifyModel.FullName, }; string updatedUserComments = JsonHelpers.AddObjectToJsonArray( order.History, JsonPropertyKeys.PostEventMaterialsWereAccessedKey, fieldsToComments ); ... /* json looks something like {"PostEventMaterialsWereAccessed":[{"Code":"rzszq","DateAdded":"2015-06-03T06:49:34.0986495","UserName":"Jonty","UserEmail":"jonty@bla.com"},{"Code":"rzszq","DateAdded":"2015-06-02T14:52:56.7051448","UserName":"harry","UserEmail":"harry@bla.com"}]} */ }
New Zealand should declare James Newton-King to be a nationl treasure.