14
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Google Cloud PlatformAdvent Calendar 2017

Day 14

.NET Core のアプリから Google Cloud Storage にアクセスする方法

Last updated at Posted at 2017-12-13

はじめに

「.NET Core で作成しているWebアプリケーションから、Google Cloud Storage(以下、GCS) にファイルを保存したい」という要件が出てきたときに調べた内容をまとめます。
主な目的はアップロードとダウンロードです。

開発環境

  • Windows 10
  • Visual Studio 2017
  • .NET Core 1.1(諸般の事情で2.x系が使えず...)

準備

  1. GCS でバケットを作成しておく(バケットの名前はあとで使います)
  2. APIの使用を許可するため、Getting Started with AuthenticationCreating a service accountSetting the environment variable を参考に、認証を通しておく
  3. nuget から Google.Cloud.Storage.V1をプロジェクトにインストールする。今回使用したバージョンは 2.1.0-alpha02 です。

バケット情報の取得

Verifying authentication では、認証が成功しているかどうかのチェックのために行われています。

バケット情報の取得
var storage = StorageClient.Create();
var buckets = storage.ListBuckets(projectId);
foreach (var bucket in buckets)
{
    Console.WriteLine(bucket.Name);
}

ファイルのアップロード

ファイルのアップロード・ダウンロードは Utility として使いたかったので、static メソッドとして定義しました。

ファイルのアップロード
/// <summary>
/// ファイルを Google Cloud Storage に保存する
/// </summary>
/// <param name="file">アップロードするファイル</param>
/// <param name="bucketName">バケット名/param>
/// <param name="path">保存先のディレクトリパス</param>
/// <param name="fileName">保存するファイル名</param>
/// <returns></returns>
public static bool SaveFileToGcs(IFormFile file, string bucketName, string path, string fileName)
{
    try
    {
        // Google Storage
        var storage = StorageClient.Create();

        using (var memoryStream = new MemoryStream())
        {
            // ファイルデータを stream にコピー
            file.CopyTo(memoryStream);

            // ストレージにアップロード アップロード先のバケットに path/fileName で保存されます
            storage.UploadObject(bucketName, path + "/" + fileName, file.ContentType,
                memoryStream);
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
        return false;
    }

    return true;
}

ファイルのダウンロード

ファイルのダウンロードはユーザーに保存のアクションをさせたかったので、 返戻値が FileStreamResult 形式になっています。

ファイルのダウンロード
/// <summary>
/// ファイルを Google Cloud Storage からダウンロードしてクライアントに保存させるActionResultを返す
/// </summary>
/// <param name="bucketName">バケット名</param>
/// <param name="targetFileName">保存したファイル名(パス含)</param>
/// <param name="contentType">コンテンツタイプ</param>
/// <returns></returns>
public static FileStreamResult DownloadFileFromGcs(string bucketName, string targetFileName, string contentType)
{
    try
    {
        var storage = StorageClient.Create();
        var memory = new MemoryStream();

        // GCS からダウンロード
        storage.DownloadObject(bucketName, targetFileName, memory);
        memory.Seek(0, SeekOrigin.Begin);

        return new FileStreamResult(memory, contentType);
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
        return null;
    }

}

おまけ:文字列をファイルにして GCS に保存する

jsonを文字列として渡されて、GCSに保存してほしい!という要件も追加できたので、文字列からファイルを作ってそのまま GCS に保存するメソッドも追加しました。

文字列から保存
/// <summary>
/// 文字列を指定されたファイル名で Google Cloud Storage に保存する
/// </summary>
/// <param name="content">ファイルとして保存する内容</param>
/// <param name="bucketName">バケット名</param>
/// <param name="path">保存先のパス</param>
/// <param name="fileName">保存ファイル名</param>
/// <param name="contentType">コンテンツタイプ</param>
/// <param name="encoding">エンコード</param>
/// <returns></returns>
public static bool SaveFileToGcs(string content, string bucketName, string path, string fileName, string contentType, Encoding encoding)
{
    try
    {
        // Google Storage
        var storage = StorageClient.Create();
        
        using (var memoryStream = new MemoryStream())
        using (var writer = new StreamWriter(memoryStream, Encoding.UTF8))
        {
            writer.WriteAsync(content);

            writer.Flush();
            memoryStream.Seek(0, SeekOrigin.Begin);

            // ストレージにアップロード
            storage.UploadObject(bucketName, path + "/" + fileName, contentType, memoryStream);
        }

    }
    catch (Exception e)
    {
        Debug.Fail(e.Message);
        return false;
    }

    return true;
}

さいごに

nuget でパッケージをいれれば特に面倒な設定とかもなく、さくっと使えて、思ってたより簡単にできました。
GCPで.NET Core で、ていうのはまだ記事は少ないような感じがします。特に日本語。
でも、どちらも公式のドキュメントがしっかりしていて、非常にやりやすいです。設計も使い勝手もわかりやすい!

さて、これからも GCP と .NET Core をどんどん使っていきますよー!

参考

14
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?