17 July, 2012

Reading and writing SharePoint field values

When working with SharePoint lists and libraries through the object model data is often retrieved or saved to and from a number of different types of fields. This blog entry will go through the different types of fields and describe how to read and write data using the object model. For each type it is defined which type of object is used to store the value, if validation is performed on the input, and how values are read and written to the field.

General info

As a general rule when working with the object model, all limits and restrictions on fields are ignored except unique value and column validation formula.

If the field does not contain any value the field value is null. This can be checked before reading the value from the field. The value can be cast to the object type that the value is stored as before it is checked for null, however this is only possible for nullable types.

Single Line of Text

The text field can contain up to 255 characters and is stored as a string object.

Read
var value = item[columnName] as string;
Write
item[columnName] = "text";
item.Update();

Multiple lines of text

This field is of type 'Note' and can be configured to contain either plain text or rich text. The content is stored as a string object.

Read
var value = item[columnName] as string;
Write
item[columnName] = "text";
item.Update();

Choice

When setting the value of a choice field there is no validation on the value, which means that the field can be set to any string (max. 255 characters). The value is stored as a string object.
Reading and writing to this type of field varies between single and multiple-choice fields.

Single choice
Read
var value = item[columnName] as string;
Write
item[columnName] = "MyChoice";
item.Update();

Multiple choice
Read
SPFieldMultiChoiceValue value = null;
if (item[columnName] != null)
    value = new SPFieldMultiChoiceValue(item[columnName] as string);
Write
To write new value:
var value = new SPFieldMultiChoiceValue();
value.Add("Choice 1");
value.Add("Choice 3");
item[columnName] = value;
item.Update();
To add a choice to selected choices:
SPFieldMultiChoiceValue value = null;
if (item[columnName] != null)
    value = new SPFieldMultiChoiceValue(item[columnName] as string);
else
    value = new SPFieldMultiChoiceValue();

value.Add("Choice 3");
item[columnName] = value;
item.Update();

Number

The number field contains a number stored as a double. Validation on minimum and maximum value is ignored when writing to the field.

Read
The value is cast to a nullable double type in order to be able to hold the null value if the field is empty.
var value = item[columnName] as Double?;
Write
item[columnName] = 11;
item.Update();

Currency

The currency field works the same way as a number field. The value is stored as a double and minimum and maximum values are ignored when writing to the field.

Read
The value is cast to a nullable double object in order to be able to hold the null value if the field is empty.
var value = item[columnName] as Double?;
To get the value including currency use the following code:
var value = item.GetFormattedValue(columnName);
Write
item[columnName] = 11;
item.Update();

Date and DateTime

Date and DateTime fields are both used the same way through the object model. When writing to the fields the full date and time is stored for both, however for the date field only the date part of the stored value is displayed. The data is stored as DateTime objects.

Read
The value is case to a nullable DateTime object in order to be able to hold the null value if the field is empty.
var value = item[columnName] as DateTime?;

Write
item[columnName] = DateTime.Now;
item.Update();

Lookup

Lookup fields are stored as string values using the format 'id:#value'. All additional fields added are accessed in the same way as the 'main' lookup field.

Reading and writing to this type of field varies between single and multiple-choice fields.

Single lookup
Read
SPFieldLookupValue value = null;
if (item[columnName] == null)
     value = new SPFieldLookupValue(item[columnName] as string);
Write
When writing simply set the value to the ID of the referenced item:
item[columnName] = 2;
item.Update();
Multiple lookup
Read
SPFieldLookupValueCollection value = null;
if (item[columnName] != null)
    value = new SPFieldLookupValueCollection(item[columnName] as string);
Write
To write new value store the IDs of the referenced list items:
var value = new SPFieldLookupValueCollection();
value.Add(new SPFieldLookupValue("2"));
value.Add(new SPFieldLookupValue("3"));
item[columnName] = value;
item.Update();
To add a lookup value to selected values add the ID of the new item to the collection:
SPFieldLookupValueCollection value;
if (item[columnName] != null)
    value = item[columnName] as SPFieldLookupValueCollection;
else
    value = new SPFieldLookupValueCollection();

value.Add(new SPFieldLookupValue("3"));
item[columnName] = value;
item.Update();

Yes/No

This type of field stores the value as a boolean.

Read
The value is case to a nullable Boolean object in order to be able to hold the null value if the field is empty.
var value = item[columnName] as Boolean?;
Write
item[columnName] = true;
item.Update();

Person or Group

Person or Group fields store their value as strings. When writing to the field user/group is not validated against the constraints defined on the field. This means that any user or group can always be stored in the field. The user from the SPFieldUserValue object can be accessed through the User property. If the User property is null the value is a group.

Reading and writing to this type of field varies between single and multi-person/group fields.

Single person/group
Read
SPFieldUserValue value = null;
if (item[columnName] != null)
{
    var userField = item.ParentList.Fields.GetFieldByInternalName(columnName);
    value = userField.GetFieldValue(item[columnName] as string) as SPFieldUserValue;
}
Write
When writing the value can be set to either the SPUser/SPGroup object or the ID of the person or the group. The following would all be valid assignments:
item[columnName] = SPContext.Current.Web.CurrentUser;
item.Update();

item[columnName] = SPContext.Current.Web.CurrentUser.ID;
item.Update();

item[columnName] = SPContext.Current.Web.Groups["MyGroup"];
item.Update();

item[columnName] = SPContext.Current.Web.Groups["MyGroup"].ID;
item.Update();
Multiple people/groups
Read
SPFieldUserValueCollection value = null;
if (item[columnName] != null) 
    value = item[columnName] as SPFieldUserValueCollection;
Write
To write new values store the IDs of the persons/groups:
var web = item.Web;
var value = new SPFieldUserValueCollection();
value.Add(new SPFieldUserValue(web, "1"));
value.Add(new SPFieldUserValue(web, "6"));
item[columnName] = value;
item.Update();
To add a person/group add the ID to the collection:
var web = item.Web;
SPFieldUserValueCollection value;
if(item[columnName] != null)
    value = item[columnName] as SPFieldUserValueCollection;
else
    value = new SPFieldUserValueCollection();
value.Add(new SPFieldUserValue(web, "6"));
item[columnName] = value;
item.Update();

Hyperlink or Picture 

The 'Hypelink or Picture' field stores an URL and a description of a hyperlink or picture. The URL must either start with the protocol e.g. 'HTTP://' or with a forward slash if it is a relative url.

Read
SPFieldUrlValue value = null;
if (item[columnName] != null)
    value = new SPFieldUrlValue(item[columnName] as string);
Write
When writing the URL can be directly written to the field. This way the description will be the same as the URL:
item[columnName] = "http://www.MyFavoriteSite.com";
item.Update();
To define both the URL and the description use the following:
var value = new SPFieldUrlValue { 
                   Url = "/_layouts/ApplicationPage.aspx", 
                   Description = "Application page link" 
            };
            
item[columnName] = value;
item.Update();

Managed Metadata

Reading and writing to this type of field varies between single and multi-managed metadata fields.

Single managed metadata
Read
var value = item[columnName] as TaxonomyFieldValue;
Write
When writing the value is set by getting the Terms from the Term Guid:
var field = item.Fields[columnName] as TaxonomyField;
var session = new TaxonomySession(item.Web.Site);
var term = session.GetTerm(termId);
field.SetFieldValue(item, term);
item.Update();
Multiple managed metadata
Read
item[columnName] as TaxonomyFieldValueCollection;
Write
When writing the value is set by getting the Terms from their Term Guids:
var field = item.Fields[columnName] as TaxonomyField;
var session = new TaxonomySession(item.Web.Site);
var terms = session.GetTerms(termIds);
field.SetFieldValue(item, terms);
item.Update();
For a complete set of extension methods for reading and writing to SharePoint fields see the blog on 'Extension Methods for SharePoint fields'.

4 comments:

  1. How would you read a SPFieldCurrency field which could be empty (i.e. optional)? Got run time NullReferenceException error when the field is empty!

    ReplyDelete
  2. This is a great reference, thank you!

    ReplyDelete
  3. Wow, Great. Really Appreciated Your work.. I will bookmark your site for a reference.. :)

    ReplyDelete