繁体   English   中英

将对象上传到 C# 中的谷歌云存储桶

[英]Uploading objects to google cloud storage buckets in c#

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

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

准备:

  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.Cloud.Storage.V1 (不是Google.Apis.Storage.v1 ),但现在执行上传似乎更简单一些。 我从客户端库的“入门”说明开始创建服务帐户和存储桶,然后尝试找出如何上传图像。

我遵循的过程是:

  1. 注册Google Cloud 免费试用
  2. 在 Google Cloud 中创建一个新项目(记住项目名称\\ID 以备后用)
  3. 创建项目所有者服务帐户- 这将导致下载包含服务帐户凭据的 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; }
}

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

  1. 必需的 api-key.json 文件
  2. 安装包 Google.Apis.Auth.OAuth2 以授权 HTTP Web 请求
  3. 您可以通过这种方式为您的应用程序设置默认配置
  4. 我使用 .NET core 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 请求。

谢谢

使用 Google.Apis.Storage.v1 在 c# 中使用 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。 您可以根据需要/要求使用相同的代码。

你会很高兴知道它在 2016 年仍然有效......我一直在谷歌上使用像“google gcp C# 上传图片”这样的花哨关键词,直到我简单地问了一个问题:“我如何将图片上传到谷歌使用 C# 的存储桶”...我在这里。 我删除了用户凭据中的.Result ,这是对我.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();
                }
            }

            // ******

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

使用c#上传文件到谷歌云存储

使用 C# .Net 将 .csv 文件上传到 Google Cloud Storage

我在C# Console Application只是为了测试目的。

@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}.");
}

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

简单,带身份验证:

    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}.");
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM