Open miracletower opened 4 years ago
Thanks @miracletower for the report, can you share the specific code calls you're calling from the Graph API?
We just provide the object from the Graph SDK, so once you've logged in, it should just be using everything from the Client Library. You may get more traction filing an issue directly on their repo as we also use their auth providers built on top of the Identity library.
FYI @darrelmiller
@michael-hawker Thank you so much for you reply. I re-organized the issue description in detail to make it much more clear.
Batch uploading files from the app's localstate folder, up into a onedrive folder, will start to fail after 7 ~ 10 times' success , unless you re-input your live id and password again and again for the authentication window raised up by every uploading request after that. (even when the login button stays in Logged-in state as the picture below shows).
Here is a screenshot of files in my onedrive's folder when the unexpected prompt happens ( each time from 7 to 10 files could be uploaded on start).
Since my project is quite complicated, I wrote a brand new project to demonstrate this issue, to make it simple and clean. According to my test on the project, the authentication windows start to prompt after 8 files uploaded to onedrive.
GrahDemo is the demo Uwp Project, please launch it first, login with your live Id, then use the built-in button to open its local state folder ( for you convenience) and copy my sample data files into it. at last, please click the start button. LocalState.zip
the core code is as below:
`private IProvider _provider; private Microsoft.Graph.GraphServiceClient _graphClient;
//files to be synchronized
List
private bool checkLoggedin()
{
if (_provider == null)
{
_provider = ProviderManager.Instance.GlobalProvider;
_graphClient = _provider.Graph;
}
return _provider != null && _provider.State == ProviderState.SignedIn;
}
private async void Start_Click(object sender, RoutedEventArgs e) { if (!checkLoggedin()) { return; } //All files are uploaded to a folder called "snowwriting" //so get file id for the folder access in advance. targetFolderId = await initializeTargetFolderId(); if (string.IsNullOrEmpty(targetFolderId)) { var dlg = new MessageDialog("The target folder is now available.", "failure"); await dlg.ShowAsync(); return; } btnStart.IsEnabled = false; generateLocalFileList(); txtStatus.Text = "synchronizing..."; foreach (string file in filesToBeSynchronized) { //upload the file, and set its description to original local directory path,
//After uploaded 7 files, the authentication windows prompts on each uploading request.
await uploadFile(file, Path.GetDirectoryName(file));
#endregion
}
txtStatus.Text = "synchronizing finished";
btnStart.IsEnabled = true;
}
private async Task<string> initializeTargetFolderId()
{
var driveItems = await _graphClient.Me.Drive.Root.Children.Request().GetAsync();
//try to get the id of folder "snowwriting", which is the target uploading folder
//create the folder if it does not exists.
var appRootItem = driveItems.Where(d => d.Name == "SnowWriting").FirstOrDefault();
if (appRootItem == null)
{
var driveItem = new Microsoft.Graph.DriveItem
{
Name = "SnowWriting",
Folder = new Microsoft.Graph.Folder { },
AdditionalData = new Dictionary<string, object>() { { "@microsoft.graph.conflictBehavior", "rename" } }
};
appRootItem = await _graphClient.Me.Drive.Root.Children.Request().AddAsync(driveItem);
if (appRootItem == null)
return string.Empty;
}
return appRootItem.Id;
}
private async Task uploadFile(string filePath, string dirPathforDescription)
{
try
{
FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
// Read byte[] from file
byte[] bytes = new byte[fileStream.Length];
fileStream.Read(bytes, 0, bytes.Length);
fileStream.Close();
using (MemoryStream ms = new MemoryStream(bytes))
{
string fileName = System.IO.Path.GetFileName(filePath);
if (bytes.Length <= 4 * 1024000)
{
var result = await _graphClient.Me.Drive.Items[targetFolderId].ItemWithPath(fileName).Content.Request().PutAsync<Microsoft.Graph.DriveItem>(ms);
if (result != null)
{
//After uploading the file, set the file's description to it's orginal local path;
Microsoft.Graph.DriveItem item = new Microsoft.Graph.DriveItem { Description = dirPathforDescription };
await _graphClient.Me.Drive.Items[result.Id].Request().UpdateAsync(item);
}
}
else
{
// Get the provider.
// POST /v1.0/drive/items/01KGPRHTV6Y2GOVW7725BZO354PWSELRRZ:/_hamiltion.png:/microsoft.graph.createUploadSession
// The CreateUploadSesssion action doesn't seem to support the options stated in the metadata.
var maxChunkSize = 320 * 1024; // 320 KB - Change this to your chunk size. 5MB is the default.
var uploadSession = await _graphClient.Drive.Items[targetFolderId].ItemWithPath(filePath).CreateUploadSession().Request().PostAsync();
var provider = new Microsoft.Graph.ChunkedUploadProvider(uploadSession, _graphClient, ms, maxChunkSize);
// Setup the chunk request necessities
var chunkRequests = provider.GetUploadChunkRequests();
var readBuffer = new byte[maxChunkSize];
var trackedExceptions = new List<Exception>();
Microsoft.Graph.DriveItem itemResult = null;
//upload the chunks
foreach (var request in chunkRequests)
{
// Do your updates here: update progress bar, etc.
// ...
// Send chunk request
var result = await provider.GetChunkRequestResponseAsync(request, readBuffer, trackedExceptions);
if (result.UploadSucceeded)
{
itemResult = result.ItemResponse;
}
}
if (itemResult != null)
{
//After uploading the file, set the file's description to it's orginal local path;
Microsoft.Graph.DriveItem item = new Microsoft.Graph.DriveItem { Description = dirPathforDescription };
await ProviderManager.Instance.GlobalProvider.Graph.Me.Drive.Items[itemResult.Id].Request().UpdateAsync(item);
}
// Check that upload succeeded
if (itemResult == null)
{
// Retry the upload
//await uploadFile(filePath);
}
}
}
}
catch (Microsoft.Graph.ServiceException e)
{
//Assert.Fail("Something happened, check out a trace. Error code: {0}", e.Error.Code);
var dlg = new MessageDialog($"Something happened, check out a trace. Error code: {e.Error.Code}", "sync error");
await dlg.ShowAsync();
}
}`
I have no idea if this is a restriction for the number of uploading files within a onedrive session or what, but it really stops my project to get its last step done.
Thanks @miracletower for the detailed info, can you copy your post & file that issue over on the .NET SDK Client repo?
Have you noticed if any exceptions are thrown or more details outputted when the auth window pops-up the first time again after starting the uploads?
The post action that brings up the auth window is as below:
var result = await _graphClient.Me.Drive.Items[targetFolderId].ItemWithPath(fileName).Content.Request().PutAsync<Microsoft.Graph.DriveItem>(ms);
ms is a memorystream from a file.
And the file, from which the uploading start to fail, is not specified.Because in my original project, and the demo project, files are being uploaded in different sequences, and each time the successful uploading number might differs. If you input liveId and pswd at the auth window, the next file could be successfully uploaded as previous files.
So I don't think it has something to do with a specific file.
I tried to use await Task.Delay(10000) before each uploading, but the auth window was remaining to pop-up after 7-10 files' success.
Futhermore, there isn't any exceptions.
since the unexpected pop-up is being "awaited" as a part of the "Content.Request().PutAsync" code.
If you cancel it, an authentication failure exception will be catched, because user canceled the loggin, but for the next file in the sequence, the window will pop-up at the "PutAsync" action again.
Thank you very much.
@michael-hawker
Hi, I`m using graph in my Uwp project, with the support from login button control. And I use IProvider.Graph as the service client object as what the sample does. My app is intended to synchronize lots of files between onedrive and local files, so that many local files will be uploaded to a specific onedrive folder. For now, with the help of this control,.I can successfully login, and start the uploading sequence. But the problem is, after uploading several files( approximately 7-10 files), the authentication windows will start to prompt eveytime the graphserviceclient trying to upload a file. If I close the authentication window, the login button control is also logged out. I spent days search for solutions, but with no luck. Please tell me where could the problem be. The provider? My tenant setting?(should it be administrator?)The login button control? Or I should have my application verified?
Thank you very much.
Document Details
⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.