C# – Creating a file under nested folder in Sharepoint

c++sharepoint

What's the best way to create a file under a nested folder in Sharepoint ?
My current method

public string CreateSPFile(string spServerURL, string spDocumentLibraryURL, string folder, string fileName, Stream fileStream, bool overwrite)
{
    if (SPSite.Exists(new Uri(spServerURL)))
    {
        SPSite site = new SPSite(spServerURL);
        SPWeb oWebsite = site.OpenWeb();
        oWebsite.AllowUnsafeUpdates = true;
        SPFolder spFolder = oWebsite.Folders[spDocumentLibraryURL];
        if (!string.IsNullOrEmpty(folder))
        {
            spFolder.SubFolders[folder].Files.Add(fileName, fileStream, overwrite);
        }
        else
        {
            SPFileCollection files = spFolder.Files;
            spFolder.Files.Add(fileName, fileStream, overwrite);
        }
        oWebsite.AllowUnsafeUpdates = false;
        site.Close();
    }
}

As you can see, if I want to create a file under nested folder, i need to modified my codes.
What will be better way to handle this kind of saving nested folder situation?

According to my project structure, the file can be like /DocumentLibrary/Folder1/Folder2/Folder3/File.txt.

Best Solution

You can load a folder by its server relative URL:

SPFolder folder = web.GetFolder("/DocumentLibrary/Folder1/Folder2/Folder3/");

With this approach you do not have to load folder by folder and your code works with n folder levels.

I've updated your code sample and added some comments regarding SharePoint best practices:

public string CreateSPFile(string spServerURL, string spDocumenttargetUrl, string folder, string fileName, Stream fileStream, bool overwrite)
{
    // I suggest skip this pre check since it internally opens a new site object
    // If you have to silenlty ignore non-existant SPSite you should catch a FileNotFoundException.
    if (SPSite.Exists(new Uri(spServerURL)))
    {
        // use the using construct to safely dispose the opened SPSite object
        using (SPSite site = new SPSite(spServerURL))
        {
            // SPWeb object opened with SPSite.OpenWeb() have to be disposed as well
            using (SPWeb web = site.OpenWeb())
            {
                web.AllowUnsafeUpdates = true;

                string targetUrl = SPUrlUtility.CombineUrl(web.ServerRelativeUrl, spDocumenttargetUrl);

                if (!String.IsNullOrEmpty(folder))
                {
                    targetUrl = SPUrlUtility.CombineUrl(targetUrl, folder);
                }

                SPFolder target = web.GetFolder(target);

                SPFileCollection files = target.Files;
                target.Files.Add(fileName, fileStream, overwrite);

                // no need to revert AllowUnsafeUpdates for newly opened webs
                // web.AllowUnsafeUpdates = false;
            }
        }
    }
}
Related Question