【问题标题】:Uploading objects to google cloud storage buckets in c#在 C# 中将对象上传到谷歌云存储桶
【发布时间】:2014-10-04 19:45:39
【问题描述】:

谁能提供一个示例,说明如何使用 Google.Apis.Storage.v1 在 c# 中将文件上传到谷歌云存储?

【问题讨论】:

    标签: c# google-cloud-storage


    【解决方案1】:

    这是针对Google.Cloud.Storage.V1(不是Google.Apis.Storage.v1),但现在执行上传似乎更简单了。我从Client libraries "Getting Started" instructions 开始创建服务帐户和存储桶,然后尝试了解如何上传图片。

    我遵循的过程是:

    1. Sign up Google Cloud 免费试用
    2. 在 Google Cloud 中创建一个新项目(记住项目名称\ID 以备后用)
    3. Create a Project Owner service account - 这将导致下载一个包含服务帐户凭据的 json 文件。记住你把那个文件放在哪里。
    4. 入门文档让您将 JSON 凭据文件的路径添加到名为 GOOGLE_APPLICATION_CREDENTIALS 的环境变量中 - 我无法通过提供的说明进行操作。事实证明这不是必需的,因为您可以将 JSON 文件读入字符串并将其传递给客户端构造函数。
    5. 我创建了一个空 WPF 项目作为起点,并创建了一个 ViewModel 来容纳应用程序逻辑。
    6. 安装Google.Cloud.Storage.V1 nuget 包,它应该会引入它需要的所有依赖项。

    进入代码。

    MainWindow.xaml

    <StackPanel>
        <Button
            Margin="50"
            Height="50"
            Content="BEGIN UPLOAD"
            Click="OnButtonClick" />
        <ContentControl
            Content="{Binding Path=ProgressBar}" />
    </StackPanel>
    

    MainWindow.xaml.cs

    public partial class MainWindow
    {
        readonly ViewModel _viewModel;
    
        public MainWindow()
        {
            _viewModel = new ViewModel(Dispatcher);
            DataContext = _viewModel;
            InitializeComponent();
        }
    
        void OnButtonClick(object sender, RoutedEventArgs args)
        {
            _viewModel.UploadAsync().ConfigureAwait(false);
        }
    }
    

    ViewModel.cs

    public class ViewModel
    {
        readonly Dispatcher _dispatcher;
    
        public ViewModel(Dispatcher dispatcher)
        {
            _dispatcher = dispatcher;
            ProgressBar = new ProgressBar {Height=30};
        }
    
        public async Task UploadAsync()
        {
            // Google Cloud Platform project ID.
            const string projectId = "project-id-goes-here";
    
            // The name for the new bucket.
            const string bucketName = projectId + "-test-bucket";
    
            // Path to the file to upload
            const string filePath = @"C:\path\to\image.jpg";
    
            var newObject = new Google.Apis.Storage.v1.Data.Object
            {
                Bucket = bucketName,
                Name = System.IO.Path.GetFileNameWithoutExtension(filePath),
                ContentType = "image/jpeg"
            };
    
            // read the JSON credential file saved when you created the service account
            var credential = Google.Apis.Auth.OAuth2.GoogleCredential.FromJson(System.IO.File.ReadAllText(
                @"c:\path\to\service-account-credentials.json"));
    
            // Instantiates a client.
            using (var storageClient = Google.Cloud.Storage.V1.StorageClient.Create(credential))
            {
                try
                {
                    // Creates the new bucket. Only required the first time.
                    // You can also create buckets through the GCP cloud console web interface
                    storageClient.CreateBucket(projectId, bucketName);
                    System.Windows.MessageBox.Show($"Bucket {bucketName} created.");
    
                    // Open the image file filestream
                    using (var fileStream = new System.IO.FileStream(filePath, System.IO.FileMode.Open))
                    {
                        ProgressBar.Maximum = fileStream.Length;
    
                        // set minimum chunksize just to see progress updating
                        var uploadObjectOptions = new Google.Cloud.Storage.V1.UploadObjectOptions
                        {
                            ChunkSize = Google.Cloud.Storage.V1.UploadObjectOptions.MinimumChunkSize
                        };
    
                        // Hook up the progress callback
                        var progressReporter = new Progress<Google.Apis.Upload.IUploadProgress>(OnUploadProgress);
    
                        await storageClient.UploadObjectAsync(
                                newObject, 
                                fileStream,
                                uploadObjectOptions,
                                progress: progressReporter)
                            .ConfigureAwait(false);
                    }
    
                }
                catch (Google.GoogleApiException e)
                    when (e.Error.Code == 409)
                {
                    // When creating the bucket - The bucket already exists.  That's fine.
                    System.Windows.MessageBox.Show(e.Error.Message);
                }
                catch (Exception e)
                {
                    // other exception
                    System.Windows.MessageBox.Show(e.Message);
                }
            }
        }
    
        // Called when progress updates
        void OnUploadProgress(Google.Apis.Upload.IUploadProgress progress)
        {
            switch (progress.Status)
            {
                case Google.Apis.Upload.UploadStatus.Starting:
                    ProgressBar.Minimum = 0;
                    ProgressBar.Value = 0;
    
                    break;
                case Google.Apis.Upload.UploadStatus.Completed:
                    ProgressBar.Value = ProgressBar.Maximum;
                    System.Windows.MessageBox.Show("Upload completed");
    
                    break;
                case Google.Apis.Upload.UploadStatus.Uploading:
                    UpdateProgressBar(progress.BytesSent);
    
                    break;
                case Google.Apis.Upload.UploadStatus.Failed:
                    System.Windows.MessageBox.Show("Upload failed"
                                                   + Environment.NewLine
                                                   + progress.Exception);
                    break;
            }
        }
    
        void UpdateProgressBar(long value)
        {
            _dispatcher.Invoke(() => { ProgressBar.Value = value; });
        }
    
        // probably better to expose progress value directly and bind to 
        // a ProgressBar in the XAML
        public ProgressBar ProgressBar { get; }
    }
    

    【讨论】:

      【解决方案2】:

      您可以通过以下方式在不使用 SDK 的情况下使用 Google Cloud API:

      1. 必需的 api-key.json 文件
      2. 安装包 Google.Apis.Auth.OAuth2 以授权 HTTP 网络请求
      3. 您可以在此设置应用程序的默认配置 方式
      4. 我使用 .NET 核心 Web API 做了同样的事情,详细信息如下:

      网址详情:

      "GoogleCloudStorageBaseUrl": "https://www.googleapis.com/upload/storage/v1/b/", "GoogleSpeechBaseUrl": "https://speech.googleapis.com/v1/operations/", "GoogleLongRunningRecognizeBaseUrl": "https://speech.googleapis.com/v1/speech:longrunningrecognize", "GoogleCloudScope": "https://www.googleapis.com/auth/cloud-platform",

      public void GetConfiguration()
          {
              // Set global configuration
              bucketName = _configuration.GetValue<string>("BucketName");
              googleCloudStorageBaseUrl = _configuration.GetValue<string>("GoogleCloudStorageBaseUrl");
              googleSpeechBaseUrl = _configuration.GetValue<string>("GoogleSpeechBaseUrl");
              googleLongRunningRecognizeBaseUrl = _configuration.GetValue<string>("GoogleLongRunningRecognizeBaseUrl");
      
              // Set google cloud credentials
              string googleApplicationCredentialsPath = _configuration.GetValue<string>("GoogleCloudCredentialPath");
              using (Stream stream = new FileStream(googleApplicationCredentialsPath, FileMode.Open, FileAccess.Read))
                  googleCredential = GoogleCredential.FromStream(stream).CreateScoped(_configuration.GetValue<string>("GoogleCloudScope"));
      
          }
      

      获取 Oauth 令牌:

      public string GetOAuthToken()
          {
              return googleCredential.UnderlyingCredential.GetAccessTokenForRequestAsync("https://accounts.google.com/o/oauth2/v2/auth", CancellationToken.None).Result;
          }
      

      上传文件到云桶:

      public async Task<string> UploadMediaToCloud(string filePath, string objectName = null)
          {
              string bearerToken = GetOAuthToken();
      
              byte[] fileBytes = File.ReadAllBytes(filePath);
              objectName = objectName ?? Path.GetFileName(filePath);
      
              var baseUrl = new Uri(string.Format(googleCloudStorageBaseUrl + "" + bucketName + "/o?uploadType=media&name=" + objectName + ""));
      
              using (WebClient client = new WebClient())
              {
                  client.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + bearerToken);
                  client.Headers.Add(HttpRequestHeader.ContentType, "application/octet-stream");
      
                  byte[] response = await Task.Run(() => client.UploadData(baseUrl, "POST", fileBytes));
                  string responseInString = Encoding.UTF8.GetString(response);
                  return responseInString;
              }
          }
      

      为了对云API执行任何操作,只需要根据要求发出HttpClient get/post请求即可。

      谢谢

      【讨论】:

        【解决方案3】:

        在 c# 中使用 Google.Apis.Storage.v1 使用 SDK 将文件上传到谷歌云存储:

        1. 所需的 api-key.json 文件

        2. 安装包 Google.Cloud.Storage.V1;和 Google.Apis.Auth.OAuth2;

        3. 下面给出了将文件上传到云端的代码

          private string UploadFile(string localPath, string objectName = null)
              {
                  string projectId = ((Google.Apis.Auth.OAuth2.ServiceAccountCredential)googleCredential.UnderlyingCredential).ProjectId;
          
                  try
                  {
                      // Creates the new bucket.
                      var objResult = storageClient.CreateBucket(projectId, bucketName);
                      if (!string.IsNullOrEmpty(objResult.Id))
                      {
                          // Upload file to google cloud server
                          using (var f = File.OpenRead(localPath))
                          {
                              objectName = objectName ?? Path.GetFileName(localPath);
                              var objFileUploadStatus1 = storageClient.UploadObject(bucketName, objectName, null, f);
                          }
                      }
                  }
                  catch (Google.GoogleApiException ex)
                  {
                      // Error code =409, means bucket already created/exist then upload file in the bucket
                      if (ex.Error.Code == 409)
                      {
                          // Upload file to google cloud server
                          using (var f = File.OpenRead(localPath))
                          {
                              objectName = objectName ?? Path.GetFileName(localPath);
                              var objFileUploadStatus2 = storageClient.UploadObject(bucketName, objectName, null, f);
                          }
                      }
                  }
                  catch (Exception ex)
                  {
                      MessageBox.Show(ex.ToString());
                  }
                  return objectName;
              }
          
          1. 设置凭据

            private bool SetStorageCredentials()
            {
                bool status = true;
                try
                {
                    if (File.Exists(credential_path))
                    {
                        Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", credential_path);
                        using (Stream objStream = new FileStream(Environment.GetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS"), FileMode.Open, FileAccess.Read))
                            googleCredential = GoogleCredential.FromStream(objStream);
                        // Instantiates a client.
                        storageClient = StorageClient.Create();
                        channel = new Grpc.Core.Channel(SpeechClient.DefaultEndpoint.Host, googleCredential.ToChannelCredentials());
                    }
                    else
                    {
                        DialogResult result = MessageBox.Show("File " + Path.GetFileName(credential_path) + " does not exist. Please provide the correct path.");
                        if (result == System.Windows.Forms.DialogResult.OK)
                        {
                            status = false;
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                    status = false;
                }
                return status;
            }
            

        我在我的一个窗口应用程序中使用了 SDK。您可以根据需要/要求使用相同的代码。

        【讨论】:

          【解决方案4】:

          我发现这个基本操作并不像你想象的那么简单。谷歌关于它的存储 API 的文档缺乏关于在 C#(或任何其他 .NET 语言)中使用它的信息。搜索“如何在 c# 中将文件上传到谷歌云存储”并没有完全帮助我,所以这是我的一些 cmets 的工作解决方案:

          准备工作:

          1. 您需要在 Google Developers Console 中创建 OAuth2 帐户 - 转到 Project/APIs & auth/Credentials。

          2. 将客户端 ID 和客户端密码复制到您的代码中。您还需要您的项目名称。

          代码(假设您已通过 NuGet 添加了 Google.Apis.Storage.v1):

          首先,您需要授权您的请求:

          var clientSecrets = new ClientSecrets();
          clientSecrets.ClientId = clientId;
          clientSecrets.ClientSecret = clientSecret;
          //there are different scopes, which you can find here https://cloud.google.com/storage/docs/authentication
          var scopes = new[] {@"https://www.googleapis.com/auth/devstorage.full_control"};
          
          var cts = new CancellationTokenSource();
          var userCredential = await GoogleWebAuthorizationBroker.AuthorizeAsync(clientSecrets,scopes, "yourGoogle@email", cts.Token);
          

          有时您可能还想通过以下方式刷新授权令牌:

          await userCredential.RefreshTokenAsync(cts.Token);
          

          您还需要创建存储服务:

          var service = new Google.Apis.Storage.v1.StorageService();
          

          现在您可以向 Google Storage API 发出请求。 让我们从创建一个新存储桶开始:

          var newBucket = new Google.Apis.Storage.v1.Data.Bucket()
          {
              Name = "your-bucket-name-1"
          };
          
          var newBucketQuery = service.Buckets.Insert(newBucket, projectName);
          newBucketQuery.OauthToken = userCredential.Result.Token.AccessToken;
          //you probably want to wrap this into try..catch block
          newBucketQuery.Execute();
          

          它已经完成了。现在,您可以发送请求以获取所有存储桶的列表:

          var bucketsQuery = service.Buckets.List(projectName);
          bucketsQuery.OauthToken = userCredential.Result.Token.AccessToken;
          var buckets = bucketsQuery.Execute();
          

          最后一部分是上传新文件:

          //enter bucket name to which you want to upload file
          var bucketToUpload = buckets.Items.FirstOrDefault().Name;
          var newObject = new Object()
          {
              Bucket = bucketToUpload,
              Name = "some-file-"+new Random().Next(1,666)
          };
          
          FileStream fileStream = null;
          try
          {
              var dir = Directory.GetCurrentDirectory();
              var path = Path.Combine(dir, "test.png");
              fileStream = new FileStream(path, FileMode.Open);
              var uploadRequest = new Google.Apis.Storage.v1.ObjectsResource.InsertMediaUpload(service, newObject,
              bucketToUpload,fileStream,"image/png");
              uploadRequest.OauthToken = userCredential.Result.Token.AccessToken;
              await uploadRequest.UploadAsync();
          }
          catch (Exception ex)
          {
              Console.WriteLine(ex.Message);
          }
          finally
          {
              if (fileStream != null)
              {
                  fileStream.Dispose();
              }
          }
          

          然后砰!新文件将显示在所选存储桶内的 Google Developers Console 中。

          【讨论】:

          • 感谢您提供详细信息以及我们将如何在我的网络应用程序中查看上传的文件,即我想访问我的应用程序中可以调用 Google 存储的网页API 并列出我网页中的所有文件?
          • 如果您在服务器端获取访问令牌,然后将其传递给客户端,客户端将继续上传文件,它会起作用吗? bucketsQuery.OauthToken = userCredential.Result.Token.AccessToken;
          • Marcin Zablocki - 你能看看stackoverflow.com/questions/55967800/…
          • 刚刚通过编译错误发现并删除了我的评论。不幸的是,API 名称经常与 VS 的名称冲突。谢谢@MarcinZablocki
          • 由于上面的原始 cmets 已被删除,我想将我的评论和回复放在更多上下文之上:代码中的 Object 类型为 Google.Apis.Storage.v1.Data。对象。
          【解决方案5】:

          您会很高兴知道它在 2016 年仍然有效... 我一直在使用诸如“google gcp C# upload image”之类的花哨关键词进行谷歌搜索,直到我简单地问了一个问题:“如何使用 C# 将图像上传到 google bucket”......我在这里。我删除了用户凭据中的.Result,这是对我有用的最终编辑。

                      // ******
          
              static string bucketForImage = ConfigurationManager.AppSettings["testStorageName"];
              static string projectName = ConfigurationManager.AppSettings["GCPProjectName"];
          
                      string gcpPath = Path.Combine(Server.MapPath("~/Images/Gallery/"), uniqueGcpName + ext);
                      var clientSecrets = new ClientSecrets();
                      clientSecrets.ClientId = ConfigurationManager.AppSettings["GCPClientID"];
                      clientSecrets.ClientSecret = ConfigurationManager.AppSettings["GCPClientSc"];
          
                      var scopes = new[] { @"https://www.googleapis.com/auth/devstorage.full_control" };
                      var cts = new CancellationTokenSource();
                      var userCredential = await GoogleWebAuthorizationBroker.AuthorizeAsync(clientSecrets, scopes, ConfigurationManager.AppSettings["GCPAccountEmail"], cts.Token);
                      var service = new Google.Apis.Storage.v1.StorageService();
                      var bucketToUpload = bucketForImage;
                      var newObject = new Google.Apis.Storage.v1.Data.Object()
                      {
                          Bucket = bucketToUpload,
                          Name = bkFileName
                      };
          
                      FileStream fileStream = null;
                      try
                      {
                          fileStream = new FileStream(gcpPath, FileMode.Open);
                          var uploadRequest = new Google.Apis.Storage.v1.ObjectsResource.InsertMediaUpload(service, newObject,
                          bucketToUpload, fileStream, "image/"+ ext);
                          uploadRequest.OauthToken = userCredential.Token.AccessToken;
                          await uploadRequest.UploadAsync();
                      }
                      catch (Exception ex)
                      {
                          Console.WriteLine(ex.Message);
                      }
                      finally
                      {
                          if (fileStream != null)
                          {
                              fileStream.Dispose();
                          }
                      }
          
                      // ******
          

          【讨论】:

          • 赞成指出对象性质:新的 Google.Apis.Storage.v1.Data.Object
          【解决方案6】:
          【解决方案7】:

          这里有 2 个示例帮助我使用 Google.Cloud.Storage.V1(不是 Google.Apis.Storage.v1)将文件上传到 Google Cloud Storage 中的存储桶:

          Upload files to Google cloud storage using c#

          Uploading .csv Files to Google Cloud Storage using C# .Net

          我两个都在 C# Console Application 上工作,只是为了测试。

          【讨论】:

            【解决方案8】:

            @2021 年 2 月

            string _projectId = "YOUR-PROJECT-ID-GCP"; //ProjectID also present in the json file
            GoogleCredential _credential = GoogleCredential.FromFile("credential-cloud-file-123418c9e06c.json");
            
            /// <summary>
            /// UploadFile to GCS Bucket
            /// </summary>
            /// <param name="bucketName"></param>
            /// <param name="localPath">my-local-path/my-file-name</param>
            /// <param name="objectName">my-file-name</param>
            public void UploadFile(string bucketName, string localPath, string objectName)
            {
                var storage = StorageClient.Create(_credential);
                using var fileStream = File.OpenRead(localPath);
                storage.UploadObject(bucketName, objectName, null, fileStream);
                Console.WriteLine($"Uploaded {objectName}.");
            }
            

            您从谷歌云门户获取凭证 JSON 文件,您可以在其中在项目下创建存储桶。

            【讨论】:

              【解决方案9】:

              简单,带有身份验证:

                  private void SaveFileToGoogleStorage(string path, string? fileName, string ext)
                  {
                      var filePath = Path.Combine(path, fileName + ext);
                      var gcCredentialsPath = Path.Combine(Environment.CurrentDirectory, "gc_sa_key.json");
                      
                      Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", gcCredentialsPath);
                      var gcsStorage = StorageClient.Create();
                      using var f = File.OpenRead(filePath);
                      var objectName = Path.GetFileName(filePath);
                      gcsStorage.UploadObject(_bucketName, objectName, null, f);
                      Console.WriteLine($"Uploaded {objectName}.");
                  }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2021-06-15
                • 2016-12-16
                • 2015-03-01
                • 2018-07-11
                • 2020-07-04
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多