Get Rid of NULL Sitecore Field Checks

Null-check is a preventive measure to avoid exceptions during run-time, yet having a bunch of it all over your solution makes for a readability horror.

Take the code below for example:

SomeClass obj = null

var field = item.Fields["Some Field"];

if(field == null)
{
    Log.Error("The field 'Some Field' is null, this);
}
else
{
    obj = SomeClass.Parse(field.Value);
}

return obj;

It doesn’t look like a lot of lines but imagine having to parse a bunch of fields throughout your development. Sure you can just create a function to encapsulate this code so it doesn’t look like it’s all over the place, but you’d still be writing the same amount of code plus the function call.

A much cleaner approach I found is to have one global function that does the standard procedure: null-check and error logging, and execute any logic passed to it. For this I’ve created an Item extension called AssumeField that accepts the name of the field and an arbitrary method, which will then simplify the above code to:

var obj = item.AssumeField("Some Field",
    field => SomeClass.Parse(field.Value));

Here’s how I’ve written the extension:

public static class ItemExtensions 
{
    public static T AssumeField<T>(this Item item, string fieldName,
        Func<Field, object> func)
    {
        var field = item.Fields[fieldName];

        if (field == null)
        {
            Log.Error($"Field '{fieldName}' does not exist.", ex, 
                new StackFrame(2).GetMethod());

            return default(T);
        }

        try
        {
            return (T) func(field);
        }
        catch (Exception ex)
        {
            Log.Error($"Some error has occured with field '{fieldName}'.", ex, 
            new StackFrame(2).GetMethod());
        }

        return default(T);
    }
}

Take note of the use of generics in this function. If you’re new to it here’s a good place to start: An Introduction to C# Generics
I’ve also used new StackFrame(2).GetMethod() to get the executing method since I wanted to pass it as the Log.Error ‘owner’ parameter.

In cases wherein you just need to execute an action based on the Field object like in the code below …

item.AssumeField("Contact Email",
    field => 
    {
        var email = field.Value;
        // Send an email
    });

just create a method overload of the AssumeField that accepts an Action instead:

public static void AssumeField(this Item item, string fieldName,
    Action<Field> action)
{
    var field = item.Fields[fieldName];

    if (field == null)
    {
        Log.Error($"Field '{fieldName}' does not exist.", ex, 
            new StackFrame(2).GetMethod());

        return;
    }

    try
    {
        action(field);
    }
    catch (Exception ex)
    {
        Log.Error($"Some error has occured with field '{fieldName}'.", ex, 
            new StackFrame(2).GetMethod());
    }
}

Happy programming!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s