views:

36

answers:

2

In our application, we store two copies of a file - an approved one and an unapproved one. Both track their versions separately. When the unapproved is then approved, all of its versions are added as new versions to the approved file. To do this properly, my code has to upload each version separately into the approved folder, and update the item each time with that version's information.

For some reason, though, this doesn't always work properly. In my latest scenario, the latest version was uploaded first, and then all of the remaining versions were uploaded afterwards. However, my code explicitly is supposed to upload the other versions first, that's the order I wrote it in. Why is this happening? And if it is possible, how do I ensure that the versions are uploaded in the correct order?

Clarification - It's not a problem with the enumeration - I'm getting the previous versions in the correct order. What is happening is that the final version, which is written after the loop, is being uploaded before the loop. Which really doesn't make any sense to me.


Here's a condensed version of the relevant code.

//These three are initialized earlier in the code.
SPList list; //The document library
SPListItem item; //The list item in the Unapproved folder
int AID; //The item id of the corresponding item in the Approved folder.

byte[] contents; //Not initialized.

/* These uploads are happening second when they should happen first. */
if (item.File.Versions.Count > 0)
{
    //This loop is actually a separate method call if that matters. 
    //For simplicity I expanded it here.
    foreach (SPFileVersion fVer in item.File.Versions)
    {
        if (!fVer.IsCurrentVersion)
        {
            contents = fVer.OpenBinary();
            SPFile fSub = aFolder.Files.Add(fVer.File.Name, contents, u1, fVer.CreatedBy, dt1, fVer.Created);
            SPListItem subItem = list.GetItemById(AID);

            //This method updates the newly uploaded version with the field data of that version.
            UpdateFields(item.Versions.GetVersionFromLabel(fVer.VersionLabel), subItem); 
        }
    }
}

/* This upload happens first when it should happen last. */
//Does the same as earlier loop, but for the final version.
contents = item.File.OpenBinary();
SPFile f = aFolder.Files.Add(item.File.Name, contents, u1, u2, dt1, dt2);
SPListItem finalItem = list.GetItemById(AID);
UpdateFields(item.Versions[0], finalItem);

item.Delete();
A: 

Why not simplify the code to use "for" instead of "foreach":

for (int i = item.File.Versions.Count - 1; i >= 0; i--)
{
    contents = item.File.Versions[i].OpenBinary();
    SPFile f = aFolder.Files.Add(item.File.Versions[i].File.Name, contents, u1, item.File.Versions[i].CreatedBy, dt1, item.File.Versions[i].Created);
    SPListItem subItem = list.GetItemByID(AID);
    UpdateFields(item.Versions.GetVersionFromLabel(item.File.Versions[i].VersionLabel), subItem);
}

This should then update in reverse order, with the first item being last.

Russ
SPFile.Versions is stored in reverse order and does not include the last version; the latest version is the SPFile itself.
ccomet
That does explain why you must do UpdateFields separately, and I see now how the code varies.If all the code is executed in a single thread, then what you have originally should work as you specified.However, the behavior you describe suggests that code in the UpdateFields method is working in a background thread, which then will prevent any control over the order. You might want to look at the code for UpdateFields to ensure that it is running in the same thread as your main code.
Russ
A: 

I think the item.File.Versions collection just returns a bunch of items and does not return them in any guaranteed order. You will be better off walking them in order explicitly than trying to foreach them and hope they come in the right order. As you've already figured out, they don't.

Aaron D
I've updated the question to properly clarify the problem. SPFile.Versions is enumerating correctly, that's not where the problem is.
ccomet