Developers: SharePoint doesn’t like you anymore

Reposted from http://sharepoint-community.net:

Even the best of friends grow apart. Sometimes your interests change and you slowly lose contact with each other. Other times the situation is more one-sided: One friend moves on to new things, leaving the other one wondering what happened.

Well guys, SharePoint has stopped answering our calls and doesn’t want to hang out with us any more. If you still think SharePoint’s your best buddy, read the signs for yourself:

You’re not invited to parties

Back in 2007 SharePoint was all “Woo! Yeah! Get yourself down here!” with farm solutions running free all over the house.

By 2010 things had started to change. SharePoint had started to hang out with it’s Power Users more. You could still come to most of the parties, but now SharePoint was asking you: “Please don’t do that thing you do. Y’know ‘code’. Unless it’s in the sandbox out back.”

Now with 2013’s app model it’s gotten even more awkward. SharePoint’s moved on from the Power Users and is in with the End User crowd: “Code? Yuk. Go do that in your own house.” The preferred method is for you to run code on your own servers, displaying the information via JavaScript.

You don’t have anything in common

When 2010 made it easier to publish code, it seemed like you were both enjoying yourselves. But SharePoint was growing restless. With it’s plans to go hosted, it started to make it more and more awkward to do things together.

At first it was making the Office 365 authentication painfully complex, leaving it to you to chase after them: “Oh, yeah. I changed my e-mail address to avoid spammers.”

Then suddenly 2013 just doesn’t support installing SharePoint for local development (see the Note): Exiling us back to the days of remote debugging: “Well, send me a letter or whatever.”

So where does that leave us?

It means if we want to stay friends with SharePoint we’re going to make all the effort and do it on their terms. They’d prefer it if they hosted nowadays, where we can code only JavaScript and HTML (if we ask nicely) and leave that old-fashioned server code thing at home.

But it’s OK because somewhere deep down SharePoint is still our friend… Right?

Easily accessing Lookup and User fields

Writing code to get or set data in a lookup field (SPFieldLookup) or its descendant the User field (SPFieldUser) can be a real pain in the eyes. Thankfully there’s a handy couple of classes that can make life easier.

If you’ve ever frowned at “;#” delimiters, and begrudgingly twisted a for clause to check every other line, then you should most definitely read on.

A bit of background

Most complex field types have a Value class; a class that handles serialising and deserialising an item’s data for that field. If the field can have multiple values then there is often also a Collection class (a generic collection in the form List<Value>).

For lookups these classes are called SPFieldLookupValue and SPFieldLookupValueCollection. For User selections these are SPFieldUserValue and SPFieldUserValueCollection.

Getting single items

If you only have one value in a lookup, then this can be accessed using the following:

SPListItem item = SPContext.Current.List.GetItemById(1);
 
if (item["LookupField"] != null)
{
     string fieldValue = item["LookupField"].ToString();
     SPFieldLookupValue value = new SPFieldLookupValue(fieldValue);
     int lookupListItemID = value.LookupId;
     string lookupListValue = value.LookupValue;
}

Not a single split string in sight. To do the same for a single user field, you do the following:

SPListItem item = SPContext.Current.List.GetItemById(1);
 
if (item["UserField"] != null)
{
     string fieldValue = item["UserField"].ToString();
     SPFieldUserValue value = new SPFieldUserValue(SPContext.Current.Web, fieldValue);
     SPUser user = value.User;
}

The SPWeb passed into the constructor above is used to resolve the User; if you’re writing cross-site code make sure you pass a Web that recognises the User.

Setting single items

Setting lookups is quite straight forward:

SPListItem item = SPContext.Current.List.GetItemById(1);
int id = 1;
item["LookupField"] = new SPFieldLookupValue(id, string.Empty);
item.Update();

id is the item ID in the lookup list, and the string.Empty is the optional (as far as I can tell) display value. The display value is populated using the ID once the item is updated, so we needn’t bother getting it ourselves.

Setting a single user field couldn’t be easier, and requires no special tools, classes, or qualifications:

item["UserField"] = SPContext.Current.Web.CurrentUser;

Multiple items

Now we’re getting into more interesting territory. Multiple choice Lookups can be accessed using the previously-mentioned SPFieldLookupValueCollection. This is a collection of SPFieldLookupValue objects that each represent one of the values.

The collection can be used to get information like this:

SPListItem item = SPContext.Current.List.GetItemById(1);
if (item["LookupField"] != null)
{
     string fieldValue = item["LookupField"].ToString();
     SPFieldLookupValueCollection values = new SPFieldLookupValueCollection(fieldValue);
     foreach (SPFieldLookupValue value in values)
     {
         int lookupListItemID = value.LookupId;
         string lookupListValue = value.LookupValue;
     }

}

And to set the item data like this:

SPListItem item = SPContext.Current.List.GetItemById(1);
SPFieldLookupValueCollection values = new SPFieldLookupValueCollection();
values.Add(new SPFieldLookupValue(1,string.Empty));
values.Add(new SPFieldLookupValue(3,string.Empty));
item["LookupField"] = values;
item.Update();

The SPFieldUserValueCollection is used in almost exactly the same way. The only differences are that the constructors require an SPWeb, and SPUser.ID is used for the LookupID.

Pretty neat

Well, I thought so.

All this was probably old news to some, but it was a Christmas stocking of happy surprises for me when I found it. 🙂