使用 Google Drive Picker (.Net) 从 Google Drive 检索文件时找不到文件异常
我在页面上放置 Google Drive Picker 时遇到了问题。
选择器自身工作正常,我从选择器返回了一个 fileid,但是当我尝试根据给定的 fileId 从服务器上的 Google Drive 下载所选文件时,我收到来自 Google 的“找不到文件”消息。
到目前为止我所做的:
- 创建了一个新的谷歌帐户;
- 创建新项目;
- 在“APIs”下的“APIs & auth”部分,启用 Google Picker API、Drive API 和 Drive SDK;
- 配置 Drive SDK 在“凭据”下的“APIs & auth”部分,添加凭据/帐户;
- 在“同意屏幕”下的“APIs & auth”部分,配置项目详细信息(电子邮件地址、产品名称);
- 在我的项目中添加了 .Net dll 的 Google Client Api ( https://www.nuget.org/packages/Google.Apis.Drive.v2/ )
以下帐户是在“凭据”部分下创建的:
- Web 应用程序的客户端 ID(这里我配置了重定向 URIS 和 Javascript ORigins。我在客户端的 Javascript 中使用了这个客户端 ID;
- Service Account,用于服务器端(我下载了谷歌生成的 P12 证书,并在后面的代码中使用了这个 Emailaddress);
我的客户端代码(基于 Google Drive Api 示例)
var developerKey = '<api_key>';
var clientId = '<client_id>';
var appId = '<app_id>';
var scope = <scopes (drive.readonly and drive.file>;
var apiLoaded = false;
var pickerApiLoaded = false;
var oauthToken;
// Use the API Loader script to load google.picker and gapi.auth.
function onApiLoad() {
apiLoaded = true;
}
function onPickerClick() {
gapi.load('auth', { 'callback': onAuthApiLoad });
gapi.load('picker', { 'callback': onPickerApiLoad });
}
function onAuthApiLoad() {
window.gapi.auth.authorize(
{
'client_id': clientId,
'scope': scope,
'immediate': false
},
handleAuthResult);
}
function onPickerApiLoad() {
pickerApiLoaded = true;
createPicker();
}
function handleAuthResult(authResult) {
if (authResult && !authResult.error) {
oauthToken = authResult.access_token;
createPicker();
}
}
function createPicker() {
if (pickerApiLoaded && oauthToken) {
var picker = new google.picker.PickerBuilder().
setAppId(appId).
addView(google.picker.ViewId.DOCUMENTS).
setOAuthToken(oauthToken).
setDeveloperKey(developerKey).
setCallback(pickerCallback).
build();
picker.setVisible(true);
}
}
function pickerCallback(data) {
if (data[google.picker.Response.ACTION] == google.picker.Action.PICKED) {
var doc = data[google.picker.Response.DOCUMENTS][0];
var fileName = document.getElementById('<%= HiddenFieldFileName.ClientID%>');
fileName.value = doc.name;
var fileId = document.getElementById('<%= HiddenFieldFileId.ClientID%>');
fileId.value = doc.id;
}
}
代码隐藏:
public IExternalFile GetFile()
{
var fileId = HiddenFieldFileId.Value;
if (!string.IsNullOrWhiteSpace(fileId))
{
try
{
var accountEmail = "<email setting from service account>";
var certificatePath = "<path to the service account certificate>";
var certificate = new X509Certificate2(certificatePath, "notasecret", X509KeyStorageFlags.Exportable);
var serviceAccount =
new ServiceAccountCredential(new ServiceAccountCredential.Initializer(accountEmail)
{
Scopes = new[] {DriveService.Scope.DriveFile, DriveService.Scope.DriveReadonly}
}.FromCertificate(certificate));
// Create the service.
var service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = serviceAccount,
ApplicationName = "<application name, configured in the Google Project"
});
var file = service.Files.Get(fileId).Execute();
var content = service.HttpClient.GetByteArrayAsync(file.DownloadUrl).Result;
var size = (content != null) ? content.Length : 0;
return new ExternalFile(file.OriginalFilename, size, content);
}
catch (Exception ex)
{
// error handling
}
}
return null;
}
错误信息:
Google.Apis.Requests.RequestError
File not found: <fileId> [404]
Errors [
Message[File not found: <fileId>] Location[ - ] Reason[notFound] Domain[global]
]
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: Google.GoogleApiException: Google.Apis.Requests.RequestError
File not found: <fileId> [404]
Errors [
Message[File not found: <fileId>] Location[ - ] Reason[notFound] Domain[global]
]