3

Any document library where the list has EnableModeration set to true causes an exception to be thrown in a powershell cmdlet that uploads a file.

The checkout, file upload, checkin, and publishing work. However, when I get to activeFile.Approve("") an exception of type SPException and message of "The file doclib/file has been modified by {FarmAccount} on {date}".

This error message is correct, the file has been modified but it has also been checked in and published. Just not approved. I have way too many files to go in and approve them all by hand in multiple places, and while I can write a console app to approve all of these after the fact, id rather nip this in the bud.

Here is the code of the segmet performing this action:

public void foo2(SPFolder folder, SPFile activeFile, string name, string filepath, ResultCollection resultsCollection)
    {
        folder.ParentWeb.AllowUnsafeUpdates = true;
        DebugLog("Replacing existing file " + name + " in folder " + folder.Url);

        try
        {
            // Force CheckinpeopleChangesPage.ListItem.File.CheckOutStatus != SPFile.SPCheckOutStatus.None
            if (activeFile.CheckOutType != SPFile.SPCheckOutType.None && activeFile.Item.ListItems.List.EnableVersioning)
            {
                activeFile.CheckIn("Forced Check-in");
            }

            if (activeFile.Item.ListItems.List.EnableVersioning)
            {
                activeFile.CheckOut();
            }

            activeFile.SaveBinary(File.ReadAllBytes(filepath));
            activeFile.Update();

            if (activeFile.Item.ListItems.List.EnableVersioning)
            {
                activeFile.CheckIn("File uploaded via api");
            }
            if (folder.ParentWeb.Lists[folder.ParentListId].EnableMinorVersions)
            {
                activeFile.Publish("Published automatically via api");
            }
            if (activeFile.Item.ListItems.List.EnableModeration)
            {
                activeFile.Approve("Approved via api");
            }

            resultsCollection.Add(new Result(true,
                                             "Replaced existing file " + name + " in folder " +
                                             folder.ParentWeb.Url + "/" + folder.Url));

        }
        catch (Exception ex)
        {
            DebugLog("Failing file replacement: " + ex.StackTrace);
            resultsCollection.Add(new Result(false,
                                             "Failed to replace " + name + " in folder " +
                                             folder.ParentWeb.Url + "/" + folder.Url + ": " +
                                             ex.Message));
        }
        finally
        {
            folder.ParentWeb.AllowUnsafeUpdates = false;
        }
    }

I had to extract it from a delegate that was going to run with elevated privileges, so forgive the name.

1 Answer 1

2

I believe that this is because calling .Update() essentially invalidates your handle to the file object as backend operations now can modify it outside of your control (workflows, approvals, event receivers, etc..) Specifically, the underlying file object has changed but your handle has not. In the past, I've had to refetch the SPFile object after calling .Update() in order to do further work with it.

5
  • Ill give that a shot and let you know how it works.
    – user5907
    Apr 17, 2012 at 15:01
  • I set activeFile = null then refetched it but am still getting the same error.
    – user5907
    Apr 17, 2012 at 15:35
  • How are you refetching the file?
    – Dave Wise
    Apr 17, 2012 at 15:38
  • activeFile = null; activeFile = folder.Files[name];
    – user5907
    Apr 17, 2012 at 15:51
  • Just tried SPListItem item = activeFile.Item; activeFile = item.File; and it worked. You definitely pointed me in the right direction. THanks!
    – user5907
    Apr 17, 2012 at 16:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.