首页 > 解决方案 > GoogleWebAuthorizationBroker.AuthorizeAsync 出错

问题描述

我正在尝试使用 C# 连接到我的 GoogleDrive。我的代码是:

    using Google.Apis.Auth.OAuth2;
using Google.Apis.Calendar.v3;
using Google.Apis.Drive.v3;
using Google.Apis.Services;
using Google.Apis.Util.Store;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;

public class GoogleDriveFiles
{
    public string Id { get; set; }
    public string Name { get; set; }
    public long? Size { get; set; }
    public long? Version { get; set; }
    public DateTime? CreatedTime { get; set; }
}

static string ApplicationName = "test";
static string[] Scopes = { CalendarService.Scope.Calendar };
string credentialsJsonFIle = "c:\\webroot\\docs\\googleDriveCredentials.json";

[Obsolete]
protected void Page_Load(object sender, EventArgs e)
{
    UserCredential credential;
    using (var stream = new FileStream(credentialsJsonFIle, FileMode.Open, FileAccess.Read))
    {
        // The file token.json stores the user's access and refresh tokens, and is created
        // automatically when the authorization flow completes for the first time.
        string credPath = @"\token.json";
        credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
            GoogleClientSecrets.Load(stream).Secrets,
            Scopes,
            "user",
            CancellationToken.None,
            new FileDataStore(credPath, true)).Result;
    }
    // Create Drive API service.
    var service = new DriveService(new BaseClientService.Initializer()
    {
        HttpClientInitializer = credential,
        ApplicationName = ApplicationName,
    });

    // Define parameters of request.
    FilesResource.ListRequest listRequest = service.Files.List();
    listRequest.PageSize = int.MaxValue;
    listRequest.Fields = "nextPageToken, files(id, name, parents, size, shared, fullFileExtension, fileExtension, version, createdTime)";

    IList<Google.Apis.Drive.v3.Data.File> files = listRequest.Execute().Files;
    
    Response.Write("Files:<br/>");
        
    FilesResource.ListRequest FileListRequest = service.Files.List();
    //get file list.
    List<GoogleDriveFiles> FileList = new List<GoogleDriveFiles>();
    string tempPath = Path.GetTempPath();

    if (files != null && files.Count > 0)
    {
        foreach (var file in files)
        {
            if (file.FileExtension == "pdf")
            {
                GoogleDriveFiles File = new GoogleDriveFiles
                {
                    Id = file.Id,
                    Name = file.Name,
                    Size = file.Size,
                    Version = file.Version,
                    CreatedTime = file.CreatedTime
                };
                FileList.Add(File);
                FilesResource.GetRequest request = service.Files.Get(file.Id);
                MemoryStream stream1 = new MemoryStream();
                string pathFile = System.IO.Path.Combine(tempPath, file.Name);

                request.Download(stream1);

                SaveStream(stream1, pathFile);
                service = new DriveService(new BaseClientService.Initializer()
                {
                    HttpClientInitializer = credential,
                    ApplicationName = ApplicationName,
                });
            }
        }
    }
    else
    {
        Response.Write("No files found.<br/>");
    }
}

我收到以下错误消息:无法访问网络位置。有关网络故障排除的信息,请参阅 Windows 帮助

在行:凭据 = GoogleWebAuthorizationBroker.AuthorizeAsync(

我的堆栈跟踪显示以下内容:

    [HttpListenerException (0x4d0): The network location cannot be reached. For information about network troubleshooting, see Windows Help]
   System.Net.HttpListener.AddAllPrefixes() +352
   System.Net.HttpListener.Start() +297
   Google.Apis.Auth.OAuth2.LocalServerCodeReceiver.StartListener() +114
   Google.Apis.Auth.OAuth2.<ReceiveCodeAsync>d__13.MoveNext() +76
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +99
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58
   Google.Apis.Auth.OAuth2.<AuthorizeAsync>d__8.MoveNext() +479
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +99
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58
   Google.Apis.Auth.OAuth2.<AuthorizeAsync>d__4.MoveNext() +422
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +99
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58
   Google.Apis.Auth.OAuth2.<AuthorizeAsync>d__1.MoveNext() +286

[AggregateException: One or more errors occurred.]
   System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions) +4323141
   System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification) +12865987
   System.Threading.Tasks.Task`1.get_Result() +33
   TestGoogleDrive.Page_Load(Object sender, EventArgs e) in c:\Webroot\www.godigix.com\test\testGoogleDrive.aspx.cs:48
   System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +51
   System.Web.UI.Control.OnLoad(EventArgs e) +95
   System.Web.UI.Control.LoadRecursive() +59
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +678

有人能帮我吗?我的 json 文件路径是正确的,并且文件存在于给定的路径中。

标签: c#google-drive-apigoogle-oauthgoogle-api-dotnet-client

解决方案


protected void Page_Load(object sender, EventArgs e)

对我来说意味着您正在尝试创建一个 Web 应用程序GoogleWebAuthorizationBroker.AuthorizeAsync是专为使用已安装的应用程序而设计的。它会在运行在网络服务器上的机器上打开同意屏幕。

对于 asp .net 核心,您需要使用依赖注入,然后您可以加载

/// <summary>
/// Lists the authenticated user's Google Drive files.
/// Specifying the <see cref="GoogleScopedAuthorizeAttribute"> will guarantee that the code
/// executes only if the user is authenticated and has granted the scope specified in the attribute
/// to this application.
/// </summary>
/// <param name="auth">The Google authorization provider.
/// This can also be injected on the controller constructor.</param>
[GoogleScopedAuthorize(DriveService.ScopeConstants.DriveReadonly)]
public async Task<IActionResult> DriveFileList([FromServices] IGoogleAuthProvider auth)
{
    GoogleCredential cred = await auth.GetCredentialAsync();
    var service = new DriveService(new BaseClientService.Initializer
    {
        HttpClientInitializer = cred
    });
    var files = await service.Files.List().ExecuteAsync();
    var fileNames = files.Files.Select(x => x.Name).ToList();
    return View(fileNames);
}

我有一个关于如何将 ASP .net 核心与 Google Profile API 一起使用的视频,它将向您展示如何配置依赖注入如何使用 C# 获取 Google 用户的个人资料信息。


推荐阅读