【问题标题】:Problems with files downloading from Google Drive Api using asp.net mvc使用 asp.net mvc 从 Google Drive Api 下载文件的问题
【发布时间】:2020-10-28 14:32:29
【问题描述】:

我可以在本地服务器上成功下载文件,但部署后我不能在不下载的情况下继续加载

  <a href="~/Home/DownloadFile/@item.Id">Download</a>

HomeController.cs

 public void DownloadFile(string id)
    {
        string FilePath = DownloadGoogleFile(id);
       
        Response.AddHeader("Content-Disposition", "attachment; filename=" + Path.GetFileName(FilePath));
        Response.WriteFile(System.Web.Hosting.HostingEnvironment.MapPath("/GoogleDriveFiles/" + Path.GetFileName(FilePath)));
        Response.End();
        Response.Flush();
    }
    static string DownloadGoogleFile(string fileId)
    {
        Google.Apis.Drive.v3.DriveService service = GetService();

        string FolderPath = System.Web.Hosting.HostingEnvironment.MapPath("/GoogleDriveFiles/");
        Google.Apis.Drive.v3.FilesResource.GetRequest request = service.Files.Get(fileId);

        string FileName = request.Execute().Name;
        string FilePath = System.IO.Path.Combine(FolderPath, FileName);

        MemoryStream stream1 = new MemoryStream();
        request.MediaDownloader.ProgressChanged += (Google.Apis.Download.IDownloadProgress progress) =>
        {
            switch (progress.Status)
            {
                case DownloadStatus.Downloading:
                    {
                        Console.WriteLine(progress.BytesDownloaded);
                        break;
                    }
                case DownloadStatus.Completed:
                    {
                        Console.WriteLine("Download complete.");
                        SaveStream(stream1, FilePath);
                        break;
                    }
            }
        };
        request.Download(stream1);
        return FilePath;
    }

   
   public static Google.Apis.Drive.v3.DriveService GetService()
    {
        var CSPath = System.Web.Hosting.HostingEnvironment.MapPath("~/");
        UserCredential credential;
        using (var stream = new FileStream(Path.Combine(CSPath, "client_secret.json"), FileMode.Open, FileAccess.Read))
        {
            
            String FilePath = Path.Combine(CSPath, "DriveServiceCredentials.json");

            credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
                GoogleClientSecrets.Load(stream).Secrets,
                Scopes,
                "user",
                CancellationToken.None,
                new FileDataStore(FilePath, true)).Result;
        }

        Google.Apis.Drive.v3.DriveService service = new Google.Apis.Drive.v3.DriveService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = credential,
            ApplicationName = "GoogleDriveRestAPI-v3",
        });

        return service;
    }

我应该改变什么?我正在尝试从谷歌获取文件,而不是从浏览器获取文件是 SSL 证书,并且确保网络与此有关,因为我的网络现在不安全?

【问题讨论】:

  • 请提供您的授权码和您的 GetService() 方法
  • 我更新代码

标签: c# asp.net asp.net-mvc google-drive-api google-api-dotnet-client


【解决方案1】:

向 Google 进行身份验证时,已安装的应用程序和网络应用程序之间存在差异。已安装应用程序可以在当前机器上的浏览器中打开授权窗口,Web 应用程序需要在用户机器上打开网络浏览器进行授权。 GoogleWebAuthorizationBroker.AuthorizeAsync 设计用于已安装的应用程序。它将在服务器上打开 Web 浏览器进行身份验证和授权。

对于 Web 应用程序,您应该使用 GoogleAuthorizationCodeFlow

using System;
using System.Web.Mvc;

using Google.Apis.Auth.OAuth2;
using Google.Apis.Auth.OAuth2.Flows;
using Google.Apis.Auth.OAuth2.Mvc;
using Google.Apis.Drive.v2;
using Google.Apis.Util.Store;

namespace Google.Apis.Sample.MVC4
{
    public class AppFlowMetadata : FlowMetadata
    {
        private static readonly IAuthorizationCodeFlow flow =
            new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
                {
                    ClientSecrets = new ClientSecrets
                    {
                        ClientId = "PUT_CLIENT_ID_HERE",
                        ClientSecret = "PUT_CLIENT_SECRET_HERE"
                    },
                    Scopes = new[] { DriveService.Scope.Drive },
                    DataStore = new FileDataStore("Drive.Api.Auth.Store")
                });

        public override string GetUserId(Controller controller)
        {
            // In this sample we use the session to store the user identifiers.
            // That's not the best practice, because you should have a logic to identify
            // a user. You might want to use "OpenID Connect".
            // You can read more about the protocol in the following link:
            // https://developers.google.com/accounts/docs/OAuth2Login.
            var user = controller.Session["user"];
            if (user == null)
            {
                user = Guid.NewGuid();
                controller.Session["user"] = user;
            }
            return user.ToString();

        }

        public override IAuthorizationCodeFlow Flow
        {
            get { return flow; }
        }
    }
}

查看完整示例here

【讨论】:

  • 是的,我正在使用 GoogleAuthorizationCodeFlow 但仍未下载
  • 您的代码显示您正在使用 GoogleWebAuthorizationBroker.AuthorizeAsync。尝试按照完整示例进行设置并确保正确控制用户会话。如果您对更改后的授权有任何问题,您可能需要打开一个新问题,因为它与这个不同。
猜你喜欢
  • 2017-11-02
  • 1970-01-01
  • 1970-01-01
  • 2015-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-06
相关资源
最近更新 更多