Find latest approved version of an SPListItem
Asked Answered
J

3

9

I am trying to iterate through the SPListItem.Versions collection to find the latest approved list item.

My list item has three versions: the first two are approved, the last is in draft. But my code says they're all in draft! Please help!

// Iterate through all versions
for (int index = 0; index < item.Versions.Count; index++)
{
    SPListItem versionedItem = item.Versions[index].ListItem;

    // Check if moderation information is set to approved
    if (versionedItem.ModerationInformation.Status.Equals(SPModerationStatusType.Approved))
    {
        // We found an approved version!
        itemFound = versionedItem;
    }
}
Jarmon answered 2/9, 2009 at 7:15 Comment(0)
B
9

item.Versions[index] returns a SPListItemVersion instance, and SPListItemVersion.ListItem returns the parent SPListItem. So your versionedItem will end up refering to the same object as item, and you're checking the same version over and over again.

I believe you actually want to check

if (item.Versions[index].Level == SPFileLevel.Published) {
  // check item.Versions[index].VersionLabel
}
Bobine answered 2/9, 2009 at 7:37 Comment(1)
It worked, thanks! Isn't it a bit awkward to get the parent like that? And the terms get mixed up if you ask me when in SharePoint you call it approval i guess, on the list its Moderation and on the list item its Level!?Jarmon
B
10

The way Mattias recommends and you have implemented is the best way to do it. It's a little awkward but still efficient as the items are ordered from most recent to oldest. This means you are likely to get a match on the published version quickly.

Expanding on the MSDN SPListItemVersionCollection article (specifically Sebastian Wojciechowski's addition):

// Current version of the item (note: this may be a draft)
SPListItem.Versions[0]

// Previous version of the item
SPListItem.Versions[1]

// First version of the item
SPListItem.Versions[SPListItem.Versions.Count - 1]
Baribaric answered 2/9, 2009 at 9:43 Comment(4)
No problem. Edited to help users find your question later.Baribaric
As the link you included now points to SharePoint 2013, and the community content you referenced is attached to the previous version: msdn.microsoft.com/en-us/library/…Anemography
@Anemography Thanks that link is fixed nowBaribaric
This seems to be the correct solution. I've seen many code snippets where they are treating item.Versions[item.Versions.Count - 1] as the newest version which is false.Conni
B
9

item.Versions[index] returns a SPListItemVersion instance, and SPListItemVersion.ListItem returns the parent SPListItem. So your versionedItem will end up refering to the same object as item, and you're checking the same version over and over again.

I believe you actually want to check

if (item.Versions[index].Level == SPFileLevel.Published) {
  // check item.Versions[index].VersionLabel
}
Bobine answered 2/9, 2009 at 7:37 Comment(1)
It worked, thanks! Isn't it a bit awkward to get the parent like that? And the terms get mixed up if you ask me when in SharePoint you call it approval i guess, on the list its Moderation and on the list item its Level!?Jarmon
J
6

My code ended up looking like this:

if (doclist.EnableVersioning)
{
    SPListItemVersionCollection allVersions = item.Versions;

    // Iterate through all versions
    foreach (SPListItemVersion version in allVersions)
    {
        if (version.Level == SPFileLevel.Published)
        {
            itemFound = version.ListItem;
        }
    }
}

Pretty neat and I really hope it works when deployed at the customer!

Jarmon answered 2/9, 2009 at 8:52 Comment(1)
Calling itemFound = version.ListItem; will return the lastest verion which may not be the Latest Approved. BewareSubmultiple

© 2022 - 2024 — McMap. All rights reserved.