Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

I have a SharePoint list (not a library) that accept the creation of folders.

I have written a small utility method that allow me to create a folder hierarchy if it does not yet exists :

    public static SPFolder EnsureFolder(SPList list, string subFolderPath)
    {
        var folderPaths = subFolderPath.Split('/');

        var currentFolder = list.RootFolder;
        for (int i = 0; i < folderPaths.Length; i++)
        {
            var subFolder = currentFolder.SubFolders.Cast<SPFolder>().FirstOrDefault(f => f.Name == folderPaths[i]);
            if (subFolder == null)
            {                   
                var newFolderItem = list.Items.Add(currentFolder.ServerRelativeUrl, SPFileSystemObjectType.Folder, folderPaths[i]);
                newFolderItem.Update();
                currentFolder.Update();
                subFolder = newFolderItem.Folder;
                list.Update();
            }
            currentFolder = subFolder;
        }
        return currentFolder;
    }

This code is working the first time but if I made two successive calls, it fails :

var myList = web.Lists["some list"];
EnsureFolder(myList, "folder");
EnsureFolder(myList, "folder"); // same as 1st call

The second calls fails on the line :

newFolderItem.Update();

with this error :

Un fichier ou un dossier nommé http://server/sites/coll/wen/Lists/somelist/folder existe déjà.     at Microsoft.SharePoint.SPGlobal.HandleComException(COMException comEx)
   at Microsoft.SharePoint.Library.SPRequest.AddOrUpdateItem(String bstrUrl, String bstrListName, Boolean bAdd, Boolean bSystemUpdate, Boolean bPreserveItemVersion, Boolean bPreserveItemUIVersion, Boolean bUpdateNoVersion, Int32& plID, String& pbstrGuid, Guid pbstrNewDocId, Boolean bHasNewDocId, String bstrVersion, Object& pvarAttachmentNames, Object& pvarAttachmentContents, Object& pvarProperties, Boolean bCheckOut, Boolean bCheckin, Boolean bMigration, Boolean bPublish, String bstrFileName, ISP2DSafeArrayWriter pListDataValidationCallback, ISP2DSafeArrayWriter pRestrictInsertCallback, ISP2DSafeArrayWriter pUniqueFieldCallback)
   at Microsoft.SharePoint.SPListItem.AddOrUpdateItem(Boolean bAdd, Boolean bSystem, Boolean bPreserveItemVersion, Boolean bNoVersion, Boolean bMigration, Boolean bPublish, Boolean bCheckOut, Boolean bCheckin, Guid newGuidOnAdd, Int32& ulID, Object& objAttachmentNames, Object& objAttachmentContents, Boolean suppressAfterEvents, String filename, Boolean bPreserveItemUIVersion)
   at Microsoft.SharePoint.SPListItem.UpdateInternal(Boolean bSystem, Boolean bPreserveItemVersion, Guid newGuidOnAdd, Boolean bMigration, Boolean bPublish, Boolean bNoVersion, Boolean bCheckOut, Boolean bCheckin, Boolean suppressAfterEvents, String filename, Boolean bPreserveItemUIVersion)
   at Microsoft.SharePoint.SPListItem.Update()
   at somewhere in my project

This can be translated as "A folder XXX already exists".

When debugging, I can see that var subFolder = currentFolder.SubFolders.Cast<SPFolder>().FirstOrDefault(f => f.Name == folderPaths[i]); will always return null. It looks like the SubFolders property is not up to date.

What have I to do to correct my code ? Am I calling the correct sequence of .Update() calls?

share|improve this question
add comment

1 Answer

up vote 1 down vote accepted

I found a simple workaround.

I rewrote the method like this :

public static SPFolder EnsureFolder(SPList list, string subFolderPath)
{
    var folderPaths = subFolderPath.Split('/');

    var currentFolder = list.RootFolder;
    for (int i = 0; i < folderPaths.Length; i++)
    {
        currentFolder = list.ParentWeb.GetFolder(currentFolder.Url); // hacky refresh
        var subFolder = currentFolder.SubFolders.Cast<SPFolder>().FirstOrDefault(f => string.Compare(f.Name, folderPaths[i], true) == 0);
        if (subFolder == null)
        {
            var newFolderItem = list.Items.Add(currentFolder.ServerRelativeUrl, SPFileSystemObjectType.Folder, folderPaths[i]);
            newFolderItem.SystemUpdate();

            subFolder = newFolderItem.Folder;
        }
        currentFolder = subFolder;
    }
    return currentFolder;
}

The trick is in this line :

 currentFolder = list.ParentWeb.GetFolder(currentFolder.Url); // hacky refresh

This line actually reload the folder, instead of relying on the yet loaded data.

Don't know if this will have side effects, but it solved my issue.

share|improve this answer
    
I was just coming back to post something similar as a suggestion after reading sharepoint.stackexchange.com/questions/20192/… Glad you got it worked out. –  RJ Cuthbertson Jul 11 '12 at 16:28
    
@rjcup3, I don't how my question (and answer) is related to the link you mentioned. Maybe I missed something? –  Steve B Jul 11 '12 at 21:06
    
Completely unrelated articles, but the answer to the one I posted talked about the web's properties not being updated / a disconnect between the actual contents and the contents of the web. It made me think of this. –  RJ Cuthbertson Jul 12 '12 at 13:08
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.