A better way to obtain fields values of an SPListItem

, , , ,

Obtaining the value of a particular field (SPField) of a list item (SPListItem) is quite awkward. First of all you have to pass either the index, Id or the InternalName of an existing field. If the field exists a value of the object type is being returned. In some cases that value can be null. If it’s not you can cast it to its origin type as in most cases defined by the SPField.FieldValueType Property. Imagine doing all that each time you want to retrieve a field value. Isn’t there a better way?

Introducing the TryGetValue extension method

To simplify the task as described above I have created an extension method using generics:

C sharp code of the try get value method

What is it doing?

The method does exactly the same what I describe above: it retrieves the value of the given field for the current list item. Because it might just happen that you’re passing an invalid id, the whole process of retrieving and processing the value is wrapped in a try catch clause.

The method encapsulates the whole process of retrieving and process the value what leads to simplification of your code. Compare the standard approach of retrieving a field value with how you would do the same using the extension method:

Comparing two different approaches of retrieving the field value from a list item. Using the extension method is more efficient than using the standard approach

See the difference? Using the extension method all you need is one line of code. The value you get is type safe and you know is different than null.

Under the hood

I have chosen to make it an extension method to make using it more intuitive. Getting the value of the particular field of the particular list item is what you want to do: why not calling the method like that?

Furthermore I have decided to use generics to provide the type safety of the retrieved value. Like that you have just one method which works for every single type out there including your custom field types:

Using the same extension method with different value types

To provide you some feedback about the value I have decided to use the try pattern. The method tries to retrieve the value of the particular field. It returns true if succeeded and false if failed. To prevent you from making an extra call to get the value I have decided to use an out parameter so you can directly use the value in your custom code.

As you’ve probably noticed in the example above I’m referring to fields using classes instead of typing the internal names. Using the latest version of Imtech Fields Explorer you can automatically generate wrapper classes for content types so you will never have to use any internal name again.

The TryGetValue extension method: do you love it or hate it?


Possibly related posts

25 Responses to “A better way to obtain fields values of an SPListItem”

  1. Erik Burger Says:

    Excellent code. I am sure it will save a lot of people a lot of hassle, including me :)

    One question/remark.

    You say at one point "Because it might just happen that you’re passing an invalid id, the whole process of retrieving and processing the value is wrapped in a try catch clause."

    Is there a specific reason why you would not use the following:

    if (listItem.Fields.ContainsField("MyDateField"))
    {
    // Enter retrieval code here
    }

    This seems to me a typical situation in which you can save yourself (and the CLR) the trouble of using Exceptions. But I might be missing something.

    Regards,
    Erik

  2. Waldek Mastykarz Says:

    Thanks for the tip Erik, I've definitely missed that one. Adding the extra check you mentioned would keep you off from getting an extra Exception but I still like the idea of having it all wrapped in a try..catch clause 'just in case'.

  3. TJ Says:

    The only problem in using the ContainsField method is it only accepts a string that contains either the display name or the internal name of the field. The wrapper classes use IDs.
    By the way Love It :-)

  4. Waldek Mastykarz Says:

    Thanks TJ :)

  5. Jim Blanchard Says:

    Quick question on your sample caller code:

    MyContentType.MyDateField

    Do you have custom classes in your code that inherit from SPContentType to do this or is there something else at play?

  6. Waldek Mastykarz Says:

    @Jim: It's a wrapper class generated using Imtech Fields Generator v1.5 (http://blog.mastykarz.nl/imtech-fields-explorer-v1410-inconvenient-site-columns-update/).

  7. Colby Africa Says:

    Thank you!

  8. nancy Says:

    Great, Thanks. question though! I have to look at all the SPListItems that are in the same list and show only those items that are not repeatetive. (I might have 3 splistitem within the same list that have the same specific field). What I want to do is to show only 1 of those splistitem instead of 3!
    Any idea????
    I REALLY appriciate any help. Thank you

  9. Waldek Mastykarz Says:

    @nancy: Unfortunately CAML doesn't provide any mechanism for selecting distinct values. What you could is to take care that you're retrieving items in a best possible way (I covered some samples here: http://blog.mastykarz.nl/performance-of-content-aggregation-queries-on-multiple-lists-revisited/) and then do the distinct selection. If the query is being run frequently it might be a good idea to cache the results as it will probably be a resource-expensive operation (depending on the total number of items of course).

  10. Demis Bellot Says:

    I think a try/catch{} is bad practice especially if you're just suppressing the exception to return false. You're better off doing something like:

    public static bool TryGetValue(this SPListItem listItem, Guid fieldId, out T value)
    {
    var oValue = listItem[fieldId];
    if (oValue != null && oValue is T)
    {
    value = (T)oValue;
    return true;
    }
    value = default(T);
    return false;
    }

  11. Waldek Mastykarz Says:

    @Demis: Fully agreed, although the try..catch is there also to suppress errors that might occur while trying to retrieve a value of a non-existing field.

  12. denisse Says:

    I have very little knowledge in c#, can someone convert this to VB and how can I actually use it? Please help!

    Thanks so much in advance!

  13. Waldek Mastykarz Says:

    @denisse: Have you tried using http://www.developerfusion.com/tools/convert/csharp-to-vb/?

  14. Panoone Says:

    Hi Waldek,

    I've installed the Imtech Field Explorer addon but receive the following exception when trying to load any URL.

    "The Web application at … could not be found. Verify that you have typed the URL correctly…"

    I have no problem accessing using other third party tools. Any idea??

  15. Waldek Mastykarz Says:

    @Panoone: Is SharePoint installed on your local machine or are you trying to access a remote site? Imtech Fields Explorer works only with local sites.

  16. Panoone Says:

    Hi Waldek, running of the server. Odd. Seems like a permission issue, perhaps as a result if running within the context if VS? Yet I have no problem with WSPBuilder, DB connects to SP through VS, or any stand-alone tools. It's an SP farm with single server + dedicated SQL box.

  17. Panoone Says:

    Forgot to mention this is a MOSS farm. :)

  18. Waldek Mastykarz Says:

    @Panoone: If you're running with UAC enabled, have you tried running the tool as admin?

  19. Panoone Says:

    No UAC but will try a Run As anyway. Do I need to append the internal port to the URL fir a host header web app?

  20. Waldek Mastykarz Says:

    @Panoone: Only if it's on a port different than 80.

  21. Panoone Says:

    Nope. It's on 80. Oh well. Will give it another shit this morning and see what happens. Is there a debug mode at all?

  22. Waldek Mastykarz Says:

    @Panoone: No, there is no debug mode. Good luck!

  23. Panoone Says:

    I think I cracked the problem. We recently upgraded our SQL server to 2008. I tired opening a DB connection to the server through VS and iot failed with the message:

    "This server is not supported. Only servers up to MS SQL 2005 are supported."

  24. Panoone Says:

    Ugh. Legacy dev VM with RTM installed. For some reason SP1 was never offered through Windows Update. Maybe a WSUS setting for web servers. Anyways…after finally locating the SP1 update and waiting am hour for it to complete, I ran an update check again. Lo and behold there were a vast number. ;)

    Will try again when it's all over. I'm done for this week.

  25. Pioter Says:

    @Demis Bellot correction for Waldek solution.
    Guys, You ommit one thing, null value is a good value for reference types (for eq string ;)). Both of you threat null as not optained value (return false)

Leave a Reply

Security Code:

WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS
Copyright © 2007 - 2012 Waldek Mastykarz

Creative Commons License