Microsoft Graph - при загрузке документов SharePoint с помощью загрузки чанка теряется HttpContext - PullRequest
1 голос
/ 17 января 2020

Мы используем MVC CRM, который использует OWIN и интегрируется в SharePoint с помощью Microsoft Graph Rest API (MSAL), и мы пытаемся загрузить файлы в библиотеку документов сайта SharePoint.

Вот код

 private const int MAX_CHUNK_SIZE = 25 * 320 * 1024;
public async static Task<bool> UploadFile(string siteName, string folderId, string filename, Stream memoryStream)
        {
            try
            { 
            var graphClient = GetAuthenticatedClient();
            var uploadSession = await CreateUploadSession(siteName, folderId, filename);
            var provider = new ChunkedUploadProvider(uploadSession, graphClient, memoryStream, MAX_CHUNK_SIZE );



            var chunkRequests = provider.GetUploadChunkRequests();
            var readBuffer = new byte[MAX_CHUNK_SIZE];
            var trackedExceptions = new List<Exception>();
            DriveItem itemResult = null;


            foreach (var request in chunkRequests)
            {

                var result = await provider.GetChunkRequestResponseAsync(request, readBuffer, trackedExceptions);

                if (result.UploadSucceeded)
                {

                    return true;
                }
            }

            if (itemResult == null)
            {
                return false;

            }

            return false;
            }
            catch(Exception ex)
            {
                throw ex;
            }
        }

Однако, когда он переходит к методу GetChunkRequestResponseAsyn c, он обращается к нашему GraphHelper для проверки аутентифицированного клиента, который имеет SessionTokenStore, но HttpContext теряется (ноль) и выбрасывает ссылку на объект, не установленную для экземпляра объекта

Код: generalException Сообщение: при отправке запроса произошла ошибка. в HomeImprover.Web.TokenStorage.SessionTokenStore.GetUsersUniqueId () в C: \ Проекты Visual Studio \ HITS \ HomeImprover.Web \ TokenStorage \ SessionTokenStore.cs: строка 112 в HomeImprover.Web.TokenTokStoreStoStoreStore , Контекст HttpContext) в C: \ Проекты Visual Studio \ HITS \ HomeImprover.Web \ TokenStorage \ SessionTokenStore.cs: строка 36 в HomeImprover.Web.Services.Graph.GraphHelper. <> c. d.MoveNext () в C: \ Проекты Visual Studio \ HITS \ HomeImprover.Web \ Services \ Graph \ GraphHelper.cs: строка 35 в System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (задача-задача) в System.Runtime. CompilerServices. Microsoft.Graph.HttpProvider.d__19.MoveNext ()

 private static GraphServiceClient GetAuthenticatedClient()
        {
            return new GraphServiceClient(
                new DelegateAuthenticationProvider(
                    async (requestMessage) =>
                    {
                        var idClient = ConfidentialClientApplicationBuilder.Create(appId)
                            .WithRedirectUri(redirectUri)
                            .WithClientSecret(appSecret)
                            .Build();

                        var tokenStore = new SessionTokenStore(idClient.UserTokenCache,
                                HttpContext.Current);

                        var accounts = await idClient.GetAccountsAsync();

                        // By calling this here, the token can be refreshed
                        // if it's expired right before the Graph call is made
                        var scopes = graphScopes.Split(' ');
                        var result = await idClient.AcquireTokenSilent(scopes, accounts.FirstOrDefault())
                            .ExecuteAsync();

                        requestMessage.Headers.Authorization =
                            new AuthenticationHeaderValue("Bearer", result.AccessToken);
                    }));
        }
 public SessionTokenStore(ITokenCache tokenCache, HttpContext context)
        {
            httpContext = context;

            if (tokenCache != null)
            {
                tokenCache.SetBeforeAccess(BeforeAccessNotification);
                tokenCache.SetAfterAccess(AfterAccessNotification);
            }

            var userId = GetUsersUniqueId();
            tokenCacheKey = $"{userId}_TokenCache";
            userCacheKey = $"{userId}_UserCache";
        }
private string GetUsersUniqueId()
        {
            return httpContext.User.Identity.GetUserId();
        }

Мы не уверены, что будем делать неправильно, поскольку MS рекомендует всегда использовать загрузку чанков, поскольку она позволяет загружать файлы размером более 4 МБ, дополнительно Мы следовали примеру загрузки, близкому к дословному.

Наконец, мы можем видеть, что временный файл начинает загружаться в документ сайта SharePoint, например, ~ tmp40_document.pdf, который добавляет часть головоломки.

Любая помощь будет оценена.

...