SharePoint: How do I upload a file structure to a document library?
My current project uses a custom 'style library' document library. The deployment process needed to replicate the files and file structure from the disk in the target library.
I used CSOM and Powershell to solve the problem.
I created a 'Common' dll that contains the methods I needed:
1. CreateFolder (to create a folder structure)
2. UploadFile (to load the file).
public static class FileHelper
{
public static Folder CreateFolder(Web web, string listTitle, string fullFolderPath)
{
if (string.IsNullOrEmpty(fullFolderPath))
throw new ArgumentNullException("fullFolderPath");
var list = web.Lists.GetByTitle(listTitle);
return CreateFolderInternal(web, list.RootFolder, fullFolderPath);
}
private static Folder CreateFolderInternal(Web web, Folder parentFolder, string fullFolderPath)
{
var folderUrls = fullFolderPath.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
string folderUrl = folderUrls[0];
var curFolder = parentFolder.Folders.Add(folderUrl);
web.Context.Load(curFolder);
web.Context.ExecuteQuery();
if (folderUrls.Length > 1)
{
var folderPath = string.Join("/", folderUrls, 1, folderUrls.Length - 1);
return CreateFolderInternal(web, curFolder, folderPath);
}
return curFolder;
}
I used CSOM and Powershell to solve the problem.
I created a 'Common' dll that contains the methods I needed:
1. CreateFolder (to create a folder structure)
2. UploadFile (to load the file).
public static class FileHelper
{
public static Folder CreateFolder(Web web, string listTitle, string fullFolderPath)
{
if (string.IsNullOrEmpty(fullFolderPath))
throw new ArgumentNullException("fullFolderPath");
var list = web.Lists.GetByTitle(listTitle);
return CreateFolderInternal(web, list.RootFolder, fullFolderPath);
}
private static Folder CreateFolderInternal(Web web, Folder parentFolder, string fullFolderPath)
{
var folderUrls = fullFolderPath.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
string folderUrl = folderUrls[0];
var curFolder = parentFolder.Folders.Add(folderUrl);
web.Context.Load(curFolder);
web.Context.ExecuteQuery();
if (folderUrls.Length > 1)
{
var folderPath = string.Join("/", folderUrls, 1, folderUrls.Length - 1);
return CreateFolderInternal(web, curFolder, folderPath);
}
return curFolder;
}
public static void UploadFile(string siteUrl, string sourceFileFullLocation, string targetListTitle, string targetLocation)
{
UploadFile(siteUrl, sourceFileFullLocation, targetListTitle, targetLocation, new Dictionary<string, string>());
}
public static void UploadFile(string siteUrl, string sourceFileFullLocation, string targetListTitle, string targetLocation, Dictionary<string, string> items)
{
using (var context = new ClientContext(siteUrl))
{
ConnectionHelper.SetCredential(context);
var web = context.Web;
context.Load(web);
context.Load(web.CurrentUser);
context.Load(web.Lists);
context.ExecuteQuery();
var newFile = new FileCreationInformation()
{
Overwrite = true,
Content = System.IO.File.ReadAllBytes(sourceFileFullLocation),
//Url = targetLocation,
Url = Path.Combine(targetLocation, Path.GetFileName(sourceFileFullLocation))
};
var targetFolder = context.Web.GetFolderByServerRelativeUrl(targetLocation);
context.Load(targetFolder);
context.ExecuteQuery();
Microsoft.SharePoint.Client.File uploadFile = targetFolder.Files.Add(newFile);
if (items != null)
{
foreach (KeyValuePair<string, string> item in items)
{
uploadFile.ListItemAllFields[item.Key] = item.Value;
}
}
uploadFile.ListItemAllFields.Update();
context.Load(uploadFile);
context.ExecuteQuery();
}
}
Once the code was compiled into a dll, I instantiated them in my powershell code:
Function LoadDll($location)
{
$bytesCommon = [System.IO.File]::ReadAllBytes("$location")
$loadResultCommon = [System.Reflection.Assembly]::Load($bytesCommon)
}
The last part is to recursively loop through the folder structure and create the items in the target location
Function UploadFiles($siteUrl, $sourceFolder, $siteRelativeUrl)
{
$listName = "MyStyleLibraryList"
CreateLibrary $siteUrl $listName
Get-ChildItem $sourceFolder -Filter *.* -Recurse |
Foreach-Object{
$name = $_.Name
$folder = $_.FullName.Replace($sourceFolder, "").Replace("\", "/")
$folder = $folder.Substring(1, $folder.Length - 1)
if ($_.PSIsContainer -eq $true)
{
Write-Host "Creating folder $folder"
CreateFolder $siteUrl $listName $folder
}
else
{
$folderWithFileName = $_.FullName.Replace("$sourceFolder", "")
$folder = $folder.Replace($_.Name, "")
UploadFile $siteUrl $_.FullName $listName "$listName/$folder" $folderWithFileName
}
}
}
Function CreateFolder($siteUrl, $listName, $folderName)
{
[MyHelperSolution.FileHelper]::CreateFolder($siteUrl, $listName, $folderName)
}
Function UploadFile($siteUrl, $sourceFolder, $listName, $siteRelativeUrl, $folderWithFile)
{
[MyHelperSoltuion.FileHelper]::UploadFile($siteUrl, $sourceFolder, $listName, $siteRelativeUrl)
}
Comments
Post a Comment