Пример надстройки SharePoint для пакетной отправки документов
Примечание.
В примере показана отправка одного файла в библиотеку документов. Для отправки нескольких файлов пример необходимо доработать.
В примере надстройки Core.BulkDocumentUploader используется консольное приложение для отправки файлов с помощью вызовов REST API. Параметры конфигурации задаются в XML- и CSV-файле.
Используйте это решение для следующих задач:
- Отправка файлов в SharePoint Online.
- Миграция в Office 365 и использование пользовательского средства миграции для перемещения файлов.
Подготовка
Чтобы приступить к работе, скачайте пример надстройки Core.BulkDocumentUploader из проекта Office 365 Developer Patterns and Practices (Шаблоны и методики разработки для Office 365) на портале GitHub.
Примечание.
Код, приведенный в этой статье, предоставляется "как есть" без какой-либо явной или подразумеваемой гарантии, включая подразумеваемые гарантии пригодности для какой-либо цели, для продажи или гарантии отсутствия нарушения прав иных правообладателей.
Прежде чем запустить этот пример кода, сделайте следующее:
Измените следующие сведения в файле OneDriveUploader.xml:
- Расположение для сохранения текстовых и CSV-файлов журналов.
- Путь к CSV-файлу сопоставления (например, C:\PnP\Samples\Core.BulkDocumentUploader\Input\SharePointSites.csv).
- Расположение файлов политик организации для отправки (например, C:\PnP\Samples\Core.BulkDocumentUploader\Input\OneDriveFiles).
- Учетные данные SharePoint Online.
- Действие, которое необходимо выполнить с документом (отправка или удаление).
- Новое имя файла, которое должно примениться к нему после отправки в библиотеку документов (например, ДОКУМЕНТ ПОЛИТИКИ ОРГАНИЗАЦИИ.xlsx).
В файле сопоставления SharePointSites.csv укажите URL-адрес библиотеки документов, в которую необходимо отправить файлы, и имя файла политики организации для отправки.
Добавьте путь к файлу OneDriveUploader.xml в качестве аргумента командной строки. Для этого откройте свойства проекта Core.BulkDocumentUploader в обозревателе решений, а затем выберите элементы Свойства>Отладка.
Использование примера надстройки Core.BulkDocumentUploader
Из метода Main в файле Program.cs метод RecurseActions вызывает метод Run в файле OneDriveMapper.cs. Метод Run получает расположение файла для отправки из файла SharePointSites.csv, а затем вызывает метод IterateCollection.
public override void Run(BaseAction parentAction, DateTime CurrentTime, LogHelper logger)
{
CsvProcessor csvProcessor = new CsvProcessor();
logger.LogVerbose(string.Format("Attempting to read mapping CSV file '{0}'", this.UserMappingCSVFile));
using (StreamReader reader = new StreamReader(this.UserMappingCSVFile))
{
csvProcessor.Execute(reader, (entries, y) => { IterateCollection(entries, logger); }, logger);
}
}
В файле SharePointSite.csv указаны файл для отправки и библиотека документов, в которую необходимо отправить этот файл. Затем метод IterateCollection выполняет следующие действия, чтобы передать файл в библиотеку документов:
Получает файл для отправки.
Проверяет у пользователя наличие разрешений на добавление элементов.
Создает объект HttpWebRequest с файлом cookie для проверки подлинности, строковый запрос REST для отправки документа и метод действия HTTP-запроса.
Выполняет отправку файла.
Примечание.
Имя файла перезаписывается значением FileUploadName, указанным в файле OneDriveUploader.xml.
public override void IterateCollection(Collection<string> entries, LogHelper logger)
{
Stopwatch IterationSW = new Stopwatch();
IterationSW.Start();
logger.LogVerbose(string.Format(CultureInfo.CurrentCulture, "Establishing context object to: '{0}'", entries[this.SiteIndex]));
try
{
// Use the context of the current iteration URL for current user item.
using (ClientContext context = new ClientContext(entries[this.SiteIndex]))
{
using (SecureString password = new SecureString())
{
foreach (char c in this.Password.ToCharArray())
{
password.AppendChar(c);
}
context.Credentials = new SharePointOnlineCredentials(this.UserName, password);
// Get the file to upload from the directory.
FileInfo theFileToUpload = new FileInfo(Path.Combine(this.DirectoryLocation + "\\", entries[this.FileIndex] + ".xlsx"));
logger.LogVerbose(string.Format(CultureInfo.CurrentCulture, "Attempting to {0} file {1}", this.DocumentAction, theFileToUpload));
// Ensure that the account has permissions to access.
BasePermissions perm = new BasePermissions();
perm.Set(PermissionKind.AddListItems);
ConditionalScope scope = new ConditionalScope(context, () => context.Web.DoesUserHavePermissions(perm).Value);
using(scope.StartScope())
{
Stopwatch tempSW = new Stopwatch();
tempSW.Start();
int success = 0;
while(tempSW.Elapsed.TotalSeconds < 20)
{
var digest = context.GetFormDigestDirect();
string cookie = ((SharePointOnlineCredentials)context.Credentials).GetAuthenticationCookie(new Uri(entries[this.SiteIndex])).TrimStart("SPOIDCRL=".ToCharArray());
using (Stream s = theFileToUpload.OpenRead())
{
// Define REST string request to upload document to context. This string specifies the Documents folder, but you can specify another document library.
string theTargetUri = string.Format(CultureInfo.CurrentCulture, "{0}/_api/web/lists/getByTitle('Documents')/RootFolder/Files/add(url='{1}',overwrite='true')?", entries[this.SiteIndex], this.FileUploadName);
// Define REST HTTP request object.
HttpWebRequest SPORequest = (HttpWebRequest)HttpWebRequest.Create(theTargetUri);
// Define HTTP request action method.
if (this.DocumentAction == "Upload")
{
SPORequest.Method = "POST";
}
else if (this.DocumentAction == "Delete")
{
SPORequest.Method = "DELETE";
}
else
{
logger.LogVerbose(string.Format(CultureInfo.CurrentCulture, "There was a problem with the HTTP request in DocumentAction attribute of XML file"));
throw new Exception("The HTTP Request operation is not supported, please check the value of DocumentAction in the XML file");
}
// Build out additional HTTP request details.
SPORequest.Accept = "application/json;odata=verbose";
SPORequest.Headers.Add("X-RequestDigest", digest.DigestValue);
SPORequest.ContentLength = s.Length;
SPORequest.ContentType = "application/octet-stream";
// Handle authentication to context through cookie.
SPORequest.CookieContainer = new CookieContainer();
SPORequest.CookieContainer.Add(new Cookie("SPOIDCRL", cookie, string.Empty, new Uri(entries[this.SiteIndex]).Authority));
// Perform file upload/deletion.
using (Stream requestStream = SPORequest.GetRequestStream())
{
s.CopyTo(requestStream);
}
// Get HTTP response to determine success of operation.
HttpWebResponse SPOResponse = (HttpWebResponse)SPORequest.GetResponse();
logger.LogVerbose(string.Format(CultureInfo.CurrentCulture, "Successfully '{0}' file {1}", this.DocumentAction, theFileToUpload));
logger.LogOutcome(entries[this.SiteIndex], "SUCCCESS");
success = 1;
// Dispose of the HTTP response.
SPOResponse.Close();
break;
}
}
tempSW.Stop();
if (success != 1)
{
throw new Exception("The HTTP Request operation exceeded the timeout of 20 seconds");
}
}
}
}
}
catch(Exception ex)
{
logger.LogVerbose(string.Format(CultureInfo.CurrentCulture, "There was an issue performing '{0}' on to the URL '{1}' with exception: {2}", this.DocumentAction, entries[this.SiteIndex], ex.Message));
logger.LogOutcome(entries[this.SiteIndex], "FAILURE");
}
finally
{
IterationSW.Stop();
logger.LogVerbose(string.Format(CultureInfo.CurrentCulture, "Completed processing URL:'{0}' in {1} seconds", entries[this.SiteIndex], IterationSW.ElapsedMilliseconds/1000));
}
}