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.)

Search Page with xPath

There’s a neat trick in the Chrome Developer Tools which not too many people are aware of. Firstly, I’m just going to run through something you should already know. You can obtain the xPath value for an element in the page by:

  1. selecting the element in the Elements tab of the chrome developer tools; and
  2. right clicking on that Element and selecting copy XPath

copyXpath
That will copy the XPath value for that element into the clipboard. Really handy for things like the XPath selector in Selenium.

Sometimes, that XPath is not exactly the way you want to write it. For example, some XPath values will be more bullet-proof in terms of selecting an element because they may handle dynamically loaded elements better than the one which we extracted using the method above. (That’s perfect for the page in the state that it is in at that moment). But we may want to re-jig that XPath so that it will still find that element every day.

Here’s the neat trick. You can open the console and run XPath expressions against the page. The syntax is to simply using a lower case ‘x’ between the ‘$’ sign and the brackets: $x('xpath here')

For example:
consoleXPatHWithArrow
Dismissed!

Test Method Snippet

I created a useful code snippet that I thought I would share. The shortcut is tm and the snippet outputs the following text, giving you the skeleton for a unit test:

[TestMethod]
public void TestMethod()
{
	//  Arrange
	
	//  Act
	
	//  Assert                        
	
}

You can download that snippet by clicking the following button:

Also, I got sick of typing mvcaction4 every time I wanted to scaffold out an Action Method. So I cracked open the snippet file for that snippet using the a text editor and changed the contents of the shortcut element to mac4. Much easier to type and very easy to remember as well!

MembershipReboot Presentation for ADNUG

On Wednesday night I delivered a presentation about MembershipReboot, a claims-aware authentication library for ASP.NET. Here are some links relevant to the content, in addition to the PowerPoint presentation which I used:

Powerpoint presentation: