Ever gotten that error message (“This functionality is unavailable for fields not associated with a list”) from Visual Studio when working with a SharePoint solution?
Ever wondered why and how to fix it?
Well OK then here is an explanation of it.
Most likely your code looks something like this:
And it´s when you call update that you´ll get this error. If we go further down to check on the GetSomeField method you´ll likely see something that looks like this:
If you have a closer look it uses the AvailableFields property on the SPWeb.
Changing that to Fields will make it work as expected again.
But why then?
Well, if we have a look (in reflector) on the different implementations on these two SPFieldCollections we this:
The code calls the constructor on the SPFieldCollection with different parameters (true vs. false).
In the SPFieldCollection constructor you´ll see this:
And later down the chain when the fields are collected from the web:
See, it uses two different stored procedures depending on whether you used AvailableField or Fields. With AvailableFields you´ll get all the fields (recursively) which is a fancy way of saying all sub sites and all parents but with Fields you´ll only get the ones on the current web.
So, if we look at the Update method on the actual SPField we´ll see:
It checks if the SPFieldCollection that the field belongs to is in fact read only and that looks like this:
And, there you go. That´s your exception right there…
In fact it´s quite realistic that we can´t update fields if don´t know their parent (the list|web) and that is what will happen when you´ll use AvailableFields.
The lesson learnt is to be aware that using AvailableFields vs Fields can be an issue if you´re planning to update the field.