© 2011 By: Dov Trietsch. All rights reserved
Dealing with Missing Fields and Default Values
New fields and new default values are not propagated throughout the list. They only apply to new and updated items and not to items already entered. They are only prospective. We need to be able to deal with this issue.
Here is a scenario. The user has an old list with old items and adds a new field. The field is not created for any of the old items. Trying to get its value raises an Argument Exception.
Here is another: a default value is added to a field. All the old items, where the field was not assigned a value, do not get the new default value. The two can also happen in tandem – a new field is added with a default. The older items have neither. Even better, if the user changes the default value, the old items still carry the old defaults.
Let’s go a bit further. You have already written code for the list, be it an event receiver, a feature receiver, a console app or a command extension, in which you span all the fields and run on selected items – some new (no problem) and some old (problems aplenty). Had you written defensive code, you would be able to handle the situation, including similar changes in the future. So, without further ado, here’s how.
Instead of just getting the value of a field in an item – item[field].ToString() – use the function below. I use ItemValue(item, fieldname, “mud in your eye”) and if “mud in your eye” is what I get, I know that the item did not have the field.
/// <summary>
/// Return the column value or a default value
/// </summary>
private static string ItemValue(SPItem item, string column, string defaultValue)
{
try
{
return item[column].ToString();
}
catch (NullReferenceException ex)
{
return defaultValue;
}
catch (ArgumentException ex)
{
return defaultValue;
}
}
I also use a similar function to return the default and a funny default-default to ascertain that the default does not exist. Here it is:
/// <summary>
/// return a fields default or the "default" default.
/// </summary>
public static string GetFieldDefault(SPField fld, string defValue)
{
try
{
// -- Check if default exists.
return fld.DefaultValue.ToString();
}
catch (NullReferenceException ex)
{
return defValue;
}
catch (ArgumentException ex)
{
return defValue;
}
}
How is this defensive? You have trapped an expected error and dealt with it. Therefore the program did not stop cold in its track and the required code ran to its end. Now, take a further step - write to a log (See Logging – a log blog). Read your own log every now and then, and act accordingly.
That’s all Folks!