Monthly Archives: July 2015

Some Json.NET Methods

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:

  1. Adds a new property to an existing Json object:
  2. public static AugmentOrderHistory(SomeViewModel viewModel, bool? createdByImpersonatedClaim)
    {
    	...
    	JProperty createdByImpersonatedUserMsg = new JProperty(
    		JsonPropertyKeys.OrderCreatedByImpersonatedUserKey,
    		createdByImpersonatedClaim.Value
    		);
    
    	newOrder.AdminComments = JsonHelpers.MergeJsonWithStoredField(
    		newOrder.AdminComments, 
    		createdByImpersonatedUserMsg
    		);
    	...
    }
    
  3. Converts a C# object to a JObject and adds it as a Json object to a Javascript array.
  4.  
    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.

Tracking Down Log4net Problems

This post is more of an FYI to myself than anything. There are a short number of steps which you need to take to debug Log4net issues when Log4net is not working. I always forget them and I am sick of navigating to the same StackOverflow question.

So, if the ADO.NET appender Log4net is not writing anything to the relevant table in your database, you need to take a look at the internal debugging built into Log4net. It’s only really 2 things that you need to do – add an app setting and a trace listener. Follow these steps to do that:

  1. add the following AppSetting to the AppSettings in your config file (Web.config or App.config as applicable):
    <add key="log4net.Internal.Debug" value="true"/>
  2. add the following trace listener:
    <system.diagnostics>
        <trace autoflush="true">
            <listeners>
                <add 
                    name="textWriterTraceListener" 
                    type="System.Diagnostics.TextWriterTraceListener" 
                    initializeData="C:\tmp\log4net.txt" />
            </listeners>
        </trace>
    </system.diagnostics>

Obviously, put that text file where ever you like on your machine.

Now you will have a log file which you can scrutinise to see what’s going on. (More often than not, there will be a typo or something in your ConnectionString.)