Загрузка файлов в и загрузка файлов из Sharepoint, защищенного 2FA, из консольного приложения C#. ⇐ C#
Загрузка файлов в и загрузка файлов из Sharepoint, защищенного 2FA, из консольного приложения C#.
Я рву на себе волосы из-за этого. Кажется, есть 1000 предложений сделать то, что я хочу, но большинство из них устарело или не работает. Документы Microsoft более чем бесполезны: они не объясняют четко принципы, вводят кучу сложных и непонятных терминов, а затем, прежде чем что-либо объяснять, разветвляются на сеть ссылок на другие страницы, которые затем делают то же самое. Всякий раз, когда я думаю, что нашел ответ, оказывается, что метод, который я рассматриваю, устарел или скоро устареет.
Итак, я задам здесь несколько вопросов и расскажу, над чем у меня работает. Во-первых, мои требования:
[*]метод должен запускаться автоматически как ежедневное запланированное задание из консольного приложения dotNet. [*]допустимо выполнять аутентификацию через веб-интерфейс 2FA только один раз при настройке задания (и, возможно, через длительные промежутки времени, например ежегодно) [*]он должен иметь возможность загружать файлы или загружать файлы с сайта SharePoint, защищенного 2FA, который не находится под моим прямым контролем, но с которым я могу связаться с владельцем и запросить внесение изменений в конфигурацию.
Что у меня работает
Благодаря этому видео мне удалось заставить работать двухфакторную аутентификацию из консольного приложения для адреса электронной почты Microsoft 365. Часть кода аутентификации выглядит следующим образом:
varscopes = new string[] { "https://graph.microsoft.com/.default" }; var secretClient = ConfidentialClientApplicationBuilder .Create(spServiceProfile.ClientID) .WithClientSecret(spServiceProfile.ClientSecret) .WithAuthority(новый Uri("https://login.microsoftonline.com/" + spServiceProfile.TenantID + "/")) .Строить(); var authResult = ожидание конфиденциального клиента .AcquireTokenForClient(области действия) .ExecuteAsync(); Итак, нам нужны три вещи: TenantID, ClientID и ClientSecret. В видео показано, как их получить или настроить.
Чтобы загрузить или скачать файл, мне нужно выбрать API или службу, которую я использую для доступа к Sharepoint. Кажется, есть два очевидных варианта: CSOM и GraphServiceClient.
Я нашел код для GraphServiceClient (но еще не пробовал его), который выглядит следующим образом:
uploadedFile = (_graphServiceClient .Сайты["корень"] .Drives["{DriveId}"] .Items["{Id_of_Targetfolder}"] .ItemWithPath(fileToUpload.FileName) .Содержимое.Запрос() .PutAsync(мс)).Result; На первый взгляд это кажется гораздо менее гибким, чем способ CSOM, для которого у меня есть рабочий код, но который прекратил аутентификацию, когда был введен 2FA, поскольку он просто вошел в систему, используя имя пользователя и пароль. Это выглядит так:
var authMgr = новый PnP.Framework.AuthenticationManager(spServiceProfile.ClientID, spServiceProfile.UserName, securePassword); используя (var rootCtx = authMgr.GetContext(rootSiteUrl)) { Uri webUri = Web.WebUrlFromPageUrlDirect(rootCtx, новый Uri(rootSiteUrl + pathUrl)); используя (var ctx = authMgr.GetContext(webUri.AbsoluteUri)) { список вар = ctx.Web.GetList(pathUrl); вар SharepointFolders = list.RootFolder.Folders; ctx.Load(sharepointFolders); ctx.ExecuteQuery(); Папка SharepointRootFolder = null; Еогеасп (вар SharepointFolder в SharepointFolders) { //s1 += "\r\n\\" +folder.Name; if (sharepointFolder.Name.ToLower() == SharePointJob.SharepointRootFolder.ToLower()) { SharepointRootFolder = SharepointFolder; } } если (fileOperation == FileOperationEnum.UploadFolder) { вар задание = (SharepointTransferFolderJobClass)sharepointJob; // циклически просматриваем все файлы в папке вар f_sarr = Directory.EnumerateFiles(job.LocalRootFolder); Еогеасп (вар localFilePath в f_sarr) { вар localFileName = Path.GetFileName(localFilePath); SharepointRootFolder.UploadFile (localFileName, job.LocalRootFolder, true); } SharepointRootFolder.Update(); ctx.Load(sharepointRootFolder); ctx.ExecuteQueryRetry(); } если (fileOperation == FileOperationEnum.DownloadFolder) { вар задание = (SharepointTransferFolderJobClass)sharepointJob; Еогеасп (вар RemoteFile в SharepointRootFolder.Files) { вар BackupFileName = RemoteFile.Name; вар SharepointFile = SharepointRootFolder.GetFile (backupFileName); ctx.Load(sharepointFile); ctx.ExecuteQueryRetry(); ClientResult поток = SharepointFile.OpenBinaryStream(); ctx.ExecuteQueryRetry(); вар destFullFilePath = Path.Combine(job.LocalRootFolder, backupFileName); используя (Stream fileStream = новый FileStream(destFullFilePath, FileMode.Create)) { CopyStream(stream.Value, fileStream); } } } } } Хорошо, итак, мы наконец перешли к вопросам:
[*]Станет ли поддержка CSOM устаревшей?
Это руководство по использованию CSOM, но вверху есть заметное предупреждение: «Модель надстройки SharePoint в настоящее время полностью поддерживается, но скоро (к концу 2023 года) она будет официально признана устаревшей в SharePoint Online». Рассмотрите возможность использования альтернативных вариантов расширения, чтобы обеспечить большую надежность вашей расширяемости в будущем.'
Я не знаю, использую ли я модель надстройки SharePoint, или это относится к CSOM в целом, и даже использую ли я Sharepoint Online (я полагаю, в отличие от локальной версии, но так ли это? на самом деле в наши дни локально для кого-либо или это просто артефакт лицензирования?).
Так будет ли мой вариант использования подпадать под прекращение поддержки, и в целом похоже ли, что CSOM движется к прекращению поддержки в долгосрочной перспективе? Или это часть долгосрочной экосистемы?
[*]Если не планируется прекращение поддержки, как мне заставить CSOM работать с моим методом аутентификации?
Мне не удалось найти ничего об их объединении, а Intellisense не дает ничего полезного.
[*]Является ли GraphServiceClient лучшим выбором в целом?
Похоже, что Graph находится на подъеме, поэтому в долгосрочной перспективе он может оказаться лучшим выбором. Но я новичок в этом и не уверен, для чего он предназначен (GraphQL заменяет REST, верно?). Использую ли я дополнительную функцию, которая может быть удалена в какой-то момент в будущем, или она именно для этого и предназначена?
Мне нужно иметь возможность выполнять такие действия, как перечисление папок и файлов SharePoint и получение дат последнего изменения. Сможет ли он это сделать?
По сути, мне нужно знать, где находятся CSOM и GraphServiceClient в экосистеме Sharepoint. Являются ли это разными инструментами, предназначенными для разных целей, и будут ли они использоваться еще долгое время? GraphServiceClient заменяет CSOM?
Спасибо за любые ответы! Раньше это было так же просто, как иметь имя пользователя и пароль. Я не сомневаюсь, что любой, кто разбирается в тонкостях всего этого, сможет построить на этом целую карьеру на данном этапе.
РЕДАКТИРОВАТЬ: спасибо за ответ @Nikolay. Публикация комментария @Jansenbe в статье, на которую есть ссылка, на случай, если ссылка исчезнет.
Чтобы полностью понять эту историю, вам нужно узнать немного больше о нашей история. 8 лет назад мы представили нашу первую библиотеку .Net под названием PnP-Сайты-Ядро. В основном это был набор расширений CSOM, которые выросли до будет очень большим набором функций, которые помогут разработчикам SharePoint. Эта библиотека поддерживалась как для SPO, так и для различных локальных версий SP. Данный требовалось все больше и больше вызовов, не связанных с CSOM + старая библиотека была не готов к современному .NET + тот факт, что локальное использование сокращалось мы решили создать новую библиотеку — PnP Core SDK. Данный PnP-Sites-Core был настолько огромным, что мы никогда не смогли бы параллельно создавать новая библиотека будет содержать все функции, а затем отправит ее на замену PnP-Sites-Core, эта трансформация займет много лет, учитывая это. реализуется как проект с открытым исходным кодом. Для этого мы ввели PnP Framework, который начинался как очищенная версия PnP-Sites-Core (весь код, специфичный для локального кода, был удален, весь «устаревшие» вещи были удалены). Люди могут перейти на PnP Framework и параллельно мы разработали PnP Core SDK и перенесли функциональность из PnP Платформа для PnP Core SDK. Например, логика API страниц живет в PnP Core SDK, но вы все равно можете вызывать его через PnP Framework, поскольку он действует. в качестве прокси.
Когда вы начинаете новый проект, рекомендуется использовать PnP Core SDK. если у вас нет зависимости от механизма обеспечения PnP (для создание и применение шаблонов сайтов). При использовании PnP Core SDK вы можете по-прежнему сталкиваемся с некоторыми недостающими функциями, но мы стараемся реагировать быстрее, и вы также можете выполнять собственные вызовы API для REST/Graph чтобы получить быстрое решение (см. https://pnp.github.io/pnpcore/using-the ... uests.html). Преимущество PnP Core SDK заключается в том, что он абстрагирует используемые API. (SharePoint REST, Microsoft Graph или SharePoint CSOM), предоставляя вам с унифицированным интерфейсом разработчика + возможность SDK заменить API реализации, когда становится больше/лучше API Microsoft Graph. доступен.
Я рву на себе волосы из-за этого. Кажется, есть 1000 предложений сделать то, что я хочу, но большинство из них устарело или не работает. Документы Microsoft более чем бесполезны: они не объясняют четко принципы, вводят кучу сложных и непонятных терминов, а затем, прежде чем что-либо объяснять, разветвляются на сеть ссылок на другие страницы, которые затем делают то же самое. Всякий раз, когда я думаю, что нашел ответ, оказывается, что метод, который я рассматриваю, устарел или скоро устареет.
Итак, я задам здесь несколько вопросов и расскажу, над чем у меня работает. Во-первых, мои требования:
[*]метод должен запускаться автоматически как ежедневное запланированное задание из консольного приложения dotNet. [*]допустимо выполнять аутентификацию через веб-интерфейс 2FA только один раз при настройке задания (и, возможно, через длительные промежутки времени, например ежегодно) [*]он должен иметь возможность загружать файлы или загружать файлы с сайта SharePoint, защищенного 2FA, который не находится под моим прямым контролем, но с которым я могу связаться с владельцем и запросить внесение изменений в конфигурацию.
Что у меня работает
Благодаря этому видео мне удалось заставить работать двухфакторную аутентификацию из консольного приложения для адреса электронной почты Microsoft 365. Часть кода аутентификации выглядит следующим образом:
varscopes = new string[] { "https://graph.microsoft.com/.default" }; var secretClient = ConfidentialClientApplicationBuilder .Create(spServiceProfile.ClientID) .WithClientSecret(spServiceProfile.ClientSecret) .WithAuthority(новый Uri("https://login.microsoftonline.com/" + spServiceProfile.TenantID + "/")) .Строить(); var authResult = ожидание конфиденциального клиента .AcquireTokenForClient(области действия) .ExecuteAsync(); Итак, нам нужны три вещи: TenantID, ClientID и ClientSecret. В видео показано, как их получить или настроить.
Чтобы загрузить или скачать файл, мне нужно выбрать API или службу, которую я использую для доступа к Sharepoint. Кажется, есть два очевидных варианта: CSOM и GraphServiceClient.
Я нашел код для GraphServiceClient (но еще не пробовал его), который выглядит следующим образом:
uploadedFile = (_graphServiceClient .Сайты["корень"] .Drives["{DriveId}"] .Items["{Id_of_Targetfolder}"] .ItemWithPath(fileToUpload.FileName) .Содержимое.Запрос() .PutAsync(мс)).Result; На первый взгляд это кажется гораздо менее гибким, чем способ CSOM, для которого у меня есть рабочий код, но который прекратил аутентификацию, когда был введен 2FA, поскольку он просто вошел в систему, используя имя пользователя и пароль. Это выглядит так:
var authMgr = новый PnP.Framework.AuthenticationManager(spServiceProfile.ClientID, spServiceProfile.UserName, securePassword); используя (var rootCtx = authMgr.GetContext(rootSiteUrl)) { Uri webUri = Web.WebUrlFromPageUrlDirect(rootCtx, новый Uri(rootSiteUrl + pathUrl)); используя (var ctx = authMgr.GetContext(webUri.AbsoluteUri)) { список вар = ctx.Web.GetList(pathUrl); вар SharepointFolders = list.RootFolder.Folders; ctx.Load(sharepointFolders); ctx.ExecuteQuery(); Папка SharepointRootFolder = null; Еогеасп (вар SharepointFolder в SharepointFolders) { //s1 += "\r\n\\" +folder.Name; if (sharepointFolder.Name.ToLower() == SharePointJob.SharepointRootFolder.ToLower()) { SharepointRootFolder = SharepointFolder; } } если (fileOperation == FileOperationEnum.UploadFolder) { вар задание = (SharepointTransferFolderJobClass)sharepointJob; // циклически просматриваем все файлы в папке вар f_sarr = Directory.EnumerateFiles(job.LocalRootFolder); Еогеасп (вар localFilePath в f_sarr) { вар localFileName = Path.GetFileName(localFilePath); SharepointRootFolder.UploadFile (localFileName, job.LocalRootFolder, true); } SharepointRootFolder.Update(); ctx.Load(sharepointRootFolder); ctx.ExecuteQueryRetry(); } если (fileOperation == FileOperationEnum.DownloadFolder) { вар задание = (SharepointTransferFolderJobClass)sharepointJob; Еогеасп (вар RemoteFile в SharepointRootFolder.Files) { вар BackupFileName = RemoteFile.Name; вар SharepointFile = SharepointRootFolder.GetFile (backupFileName); ctx.Load(sharepointFile); ctx.ExecuteQueryRetry(); ClientResult поток = SharepointFile.OpenBinaryStream(); ctx.ExecuteQueryRetry(); вар destFullFilePath = Path.Combine(job.LocalRootFolder, backupFileName); используя (Stream fileStream = новый FileStream(destFullFilePath, FileMode.Create)) { CopyStream(stream.Value, fileStream); } } } } } Хорошо, итак, мы наконец перешли к вопросам:
[*]Станет ли поддержка CSOM устаревшей?
Это руководство по использованию CSOM, но вверху есть заметное предупреждение: «Модель надстройки SharePoint в настоящее время полностью поддерживается, но скоро (к концу 2023 года) она будет официально признана устаревшей в SharePoint Online». Рассмотрите возможность использования альтернативных вариантов расширения, чтобы обеспечить большую надежность вашей расширяемости в будущем.'
Я не знаю, использую ли я модель надстройки SharePoint, или это относится к CSOM в целом, и даже использую ли я Sharepoint Online (я полагаю, в отличие от локальной версии, но так ли это? на самом деле в наши дни локально для кого-либо или это просто артефакт лицензирования?).
Так будет ли мой вариант использования подпадать под прекращение поддержки, и в целом похоже ли, что CSOM движется к прекращению поддержки в долгосрочной перспективе? Или это часть долгосрочной экосистемы?
[*]Если не планируется прекращение поддержки, как мне заставить CSOM работать с моим методом аутентификации?
Мне не удалось найти ничего об их объединении, а Intellisense не дает ничего полезного.
[*]Является ли GraphServiceClient лучшим выбором в целом?
Похоже, что Graph находится на подъеме, поэтому в долгосрочной перспективе он может оказаться лучшим выбором. Но я новичок в этом и не уверен, для чего он предназначен (GraphQL заменяет REST, верно?). Использую ли я дополнительную функцию, которая может быть удалена в какой-то момент в будущем, или она именно для этого и предназначена?
Мне нужно иметь возможность выполнять такие действия, как перечисление папок и файлов SharePoint и получение дат последнего изменения. Сможет ли он это сделать?
По сути, мне нужно знать, где находятся CSOM и GraphServiceClient в экосистеме Sharepoint. Являются ли это разными инструментами, предназначенными для разных целей, и будут ли они использоваться еще долгое время? GraphServiceClient заменяет CSOM?
Спасибо за любые ответы! Раньше это было так же просто, как иметь имя пользователя и пароль. Я не сомневаюсь, что любой, кто разбирается в тонкостях всего этого, сможет построить на этом целую карьеру на данном этапе.
РЕДАКТИРОВАТЬ: спасибо за ответ @Nikolay. Публикация комментария @Jansenbe в статье, на которую есть ссылка, на случай, если ссылка исчезнет.
Чтобы полностью понять эту историю, вам нужно узнать немного больше о нашей история. 8 лет назад мы представили нашу первую библиотеку .Net под названием PnP-Сайты-Ядро. В основном это был набор расширений CSOM, которые выросли до будет очень большим набором функций, которые помогут разработчикам SharePoint. Эта библиотека поддерживалась как для SPO, так и для различных локальных версий SP. Данный требовалось все больше и больше вызовов, не связанных с CSOM + старая библиотека была не готов к современному .NET + тот факт, что локальное использование сокращалось мы решили создать новую библиотеку — PnP Core SDK. Данный PnP-Sites-Core был настолько огромным, что мы никогда не смогли бы параллельно создавать новая библиотека будет содержать все функции, а затем отправит ее на замену PnP-Sites-Core, эта трансформация займет много лет, учитывая это. реализуется как проект с открытым исходным кодом. Для этого мы ввели PnP Framework, который начинался как очищенная версия PnP-Sites-Core (весь код, специфичный для локального кода, был удален, весь «устаревшие» вещи были удалены). Люди могут перейти на PnP Framework и параллельно мы разработали PnP Core SDK и перенесли функциональность из PnP Платформа для PnP Core SDK. Например, логика API страниц живет в PnP Core SDK, но вы все равно можете вызывать его через PnP Framework, поскольку он действует. в качестве прокси.
Когда вы начинаете новый проект, рекомендуется использовать PnP Core SDK. если у вас нет зависимости от механизма обеспечения PnP (для создание и применение шаблонов сайтов). При использовании PnP Core SDK вы можете по-прежнему сталкиваемся с некоторыми недостающими функциями, но мы стараемся реагировать быстрее, и вы также можете выполнять собственные вызовы API для REST/Graph чтобы получить быстрое решение (см. https://pnp.github.io/pnpcore/using-the ... uests.html). Преимущество PnP Core SDK заключается в том, что он абстрагирует используемые API. (SharePoint REST, Microsoft Graph или SharePoint CSOM), предоставляя вам с унифицированным интерфейсом разработчика + возможность SDK заменить API реализации, когда становится больше/лучше API Microsoft Graph. доступен.
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
C# Запуск консольного приложения из другого приложения в новом окне консоли
Anonymous » » в форуме C# - 0 Ответы
- 21 Просмотры
-
Последнее сообщение Anonymous
-