我正在编写一个程序,允许用户将文件上传到他们的Google云端硬盘帐户。我有上传部分工作,我正在使用OAuth2。我目前遇到的问题是从用户云端硬盘帐户中获取文件夹列表。
我发现了一些应该使用.setUserCredentials方法执行此操作的代码,但它不起作用:
DocumentsService service1 = new DocumentsService("project");
service1.setUserCredentials("user","pass");
FolderQuery query1 = new FolderQuery();
// Make a request to the API and get all documents.
DocumentsFeed feed = service1.Query(query1);
// Iterate through all of the documents returned
foreach (DocumentEntry entry in feed.Entries)
{
var blech = entry.Title.Text;
}
没有返回任何内容。理想情况下,我想使用OAuth2来执行此操作。我一直在尝试使用以下代码,尝试设置身份验证令牌,但我总是被拒绝访问:
String CLIENT_ID = "clientid";
String CLIENT_SECRET = "secretid";
var docprovider = new NativeApplicationClient(GoogleAuthenticationServer.Description, CLIENT_ID, CLIENT_SECRET);
var docstate = GetDocAuthentication(docprovider);
DocumentsService service1 = new DocumentsService("project");
service1.SetAuthenticationToken(docstate.RefreshToken);
FolderQuery query1 = new FolderQuery();
DocumentsFeed feed = service1.Query(query1); //get error here
// Iterate through all of the documents returned
foreach (DocumentEntry entry in feed.Entries)
{
// Print the title of this document to the screen
var blech = entry.Title.Text;
}
...
private static IAuthorizationState GetDocAuthentication(NativeApplicationClient client)
{
const string STORAGE = "storagestring";
const string KEY = "keystring";
string scope = "https://docs.google.com/feeds/default/private/full/-/folder";
// Check if there is a cached refresh token available.
IAuthorizationState state = AuthorizationMgr.GetCachedRefreshToken(STORAGE, KEY);
if (state != null)
{
try
{
client.RefreshToken(state);
return state; // Yes - we are done.
}
catch (DotNetOpenAuth.Messaging.ProtocolException ex)
{
}
}
// Retrieve the authorization from the user.
state = AuthorizationMgr.RequestNativeAuthorization(client, scope);
AuthorizationMgr.SetCachedRefreshToken(STORAGE, KEY, state);
return state;
}
具体来说,我得到“执行请求失败:https://docs.google.com/feeds/default/private/full/-/folder - 远程服务器返回错误:(401)未经授权”。
我也试过了:
var docauth = new OAuth2Authenticator<NativeApplicationClient>(docprovider, GetDocAuthentication);
DocumentsService service1 = new DocumentsService("project");
service1.SetAuthenticationToken(docauth.State.AccessToken);
但“State”始终为null,因此我得到一个null对象错误。我做错了什么,这是怎么做到的?
答案 0 :(得分:3)
您应该使用Drive SDK,而不是文档列表API,它允许您list folders。如果要列出根目录,可以使用“root”作为folderId。
答案 1 :(得分:0)
private IEnumerable<DocumentEntry> GetFolders(string id) {
if (IsLogged) {
var query = new FolderQuery(id)
{
ShowFolders = true
};
var feed = GoogleDocumentsService.Query(query);
return feed.Entries.Cast<DocumentEntry>().Where(x => x.IsFolder).OrderBy(x => x.Title.Text);
}
return null;
}
...
var rootFolders = GetFolders("root");
if (rootFolders != null){
foreach(var folder in rootFolders){
var subFolders = GetFolders(folder.ResourceId);
...
}
}
其中GoogleDocumentsService
是DocumentsService
的实例,IsLogged
是成功记录的标记。
答案 2 :(得分:0)
我有这样的方法来获取谷歌驱动器中的文件夹列表
FilesResource.ListRequest filelist= service.Files.List();
filelist.Execute().Items.ToList().Where(x => x.MimeType == "application/vnd.google-apps.folder").ToList()
答案 3 :(得分:0)
我实际上实现了适用于.NET的GDrive SDK v3版本,还需要搜索文件夹。
我更喜欢唯一地请求所有文件夹,而不是获取所有文件,然后执行LinQ查询以仅保留文件夹。
这是我的实现方式
private async Task<bool> FolderExistsAsync(string folderName)
{
var response = await GetAllFoldersAsync();
return response.Files
.Where(x => x.Name.ToLower() == folderName.ToLower())
.Any();
}
private async Task<Google.Apis.Drive.v3.Data.FileList> GetAllFoldersAsync()
{
var request = _service.Files.List();
request.Q = "mimeType = 'application/vnd.google-apps.folder'";
var response = await request.ExecuteAsync();
return response;
}
您也可以通过以下方式在Q
上请求名称:
request.Q = $"mimeType = 'application/vnd.google-apps.folder' and name = '{folderName}'";
这将导致并简化(避免null
检查):
private async Task<bool> FolderExistsAsync(string folderName)
{
var response = await GetDesiredFolder(folderName);
return response.Files.Any();
}
private async Task<FileList> GetDesiredFolder(string folderName)
{
var request = _service.Files.List();
request.Q = $"mimeType = 'application/vnd.google-apps.folder' and name = '{folderName}'";
var response = await request.ExecuteAsync();
return response;
}