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.