Sunday, March 17, 2013

Using SharePoint Field Internal Name
 

In SharePoint, you can use either field Display Name (Title) or Internal Name to reference a field. However "Internal Name" does not work in some senarios.

Display Name is different from Internal Name. Usually the display name will have format like "E-Mail Body", but the internal name will be like "E_x002d_Mail_x0020_Body0"


1. You can use either "Display Name" or "Internal Name" to retrieve item column data.

For example, the next two line will return same result for column "E-Mail Body".
 
string itemValue1 = list.Items[0]["E-Mail Body"] as string;
string itemValue2 = list.Items[0]["E_x002d_Mail_x0020_Body0"] as string;


2. Testing if the field exists with List.Fields.Contains, either "Display Name" or "Internal Name" will return true.

Both next two line will return true.
list.Fields.ContainsField("E-Mail Body")
list.Fields.ContainsField("E_x002d_Mail_x0020_Body0")
3. However, when retrieving SPField using List.Fields, internal name will cause exception.

The 2nd line will throw exception even when you had tested it with ContainsField and the result is true.
list.Fields["E-Mail Body"];

list.Fields["E_x002d_Mail_x0020_Body0"]
To avoid exception, you use

list.Fields.GetFieldByInternalName("E_x002d_Mail_x0020_Body0")

So when you are trying to write a method to return the internal field name of a field, be careful with the exception with List.Fields indexer

public static string GetInternalFieldName(SPList list, string fieldName)
{

    try
   {
              if (list.Fields.ContainsField(fieldName)) // both display name and internal name will return true
             {
                     SPField field = list.Fields[fieldName]; // however internal name will cause exception. Catch the exception and return the name as it is.
                     return field.InternalName;
             }
             else
                     return null;
     }
     catch
     {
             // if fieldName is internal field name, exception will be thrown
            return fieldName;
     }
}

4. Internal Name can only be used to build CAML query or with listView.ViewFields.Exists
SPQuery query = new SPQuery();
String fieldInternalName = GetInternalFieldName(list, lookupFieldName);
query.Query = "<Where><Eq><FieldRef LookupId='True' Name='" + fieldInternalName + "' /><Value Type='Lookup'>" + id + "</Value></Eq></Where>";
SPListItemCollection items = list.GetItems(query);
return items;

string internalFieldName = GetInternalFieldName(list, fieldName);
// Add Field to default view

SPView listView = list.DefaultView;
if (!listView.ViewFields.Exists(internalFieldName))
{
listView.ViewFields.Add(fieldName);
listView.Update();
}

3 comments: