Lightning Blog
Blazor記事イメージ画像

【Blazor】 AWS S3にアクセスする方法

更新日:2024/05/21
この記事では、BlazorアプリケーションからSDKを使って、 AWS S3にアクセスするためのサービスクラスの実装例について解説していきます。

    目次

  • 必要なライブラリのインストール
  • AWS S3にアクセスするのに必要な情報や権限
  • S3にアクセスするサービスクラスを作成
  • まとめ

必要なライブラリのインストール

セクション画像

[Nugetパッケージの管理]からAWSSDK.S3の最新版をインストールします。

※この記事を書いている時点では、Version 3.7.307.4が最新となっています。


AWS S3にアクセスするのに必要な情報や権限

セクション画像

SDKを使って、S3へアクセスするためには、以下の情報が必要になります。

必要な情報 説明
アクセスキー アクセスキーは、AWSサービスを利用するために必要なユーザー名のようなものです。
シークレットキー アクセスキーとペアで使用される認証情報です。パスワードのような役割を果たします。
バケット名 AWS S3でデータを保存するためのオブジェクトをバケットと呼びますが、バケット名は、そのバケットを一意に識別するための名前です。
リージョン AWSが世界中に設置しているデータセンターの場所のことです。

また今回は、S3へのアクセスしてオブジェクトを取得するための権限を付与する必要があります。 以下は、IAMポリシーで権限を定義した例です。


{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}

この例では、GetObjectというアクションをすべてのリソース(*)に対して許可しています。 案件によって、権限等が異なると思いますので、随時調整してください。


S3にアクセスするサービスクラスを作成

セクション画像

AWS S3にアクセスするためのサービスクラスを実装していきます。 以下は実装したコードの全体像になります。


/// <summary>
/// AWS S3アクセス用サービス
/// </summary>
public class S3Service
{
    /// <summary>
    /// アクセスキー
    /// </summary>
    private readonly string _accessKey;

    /// <summary>
    /// シークレットキー
    /// </summary>
    private readonly string _secretKey;

    /// <summary>
    /// バケット名
    /// </summary>
    private readonly string _bucketName;

    /// <summary>
    /// リージョン
    /// </summary>
    private readonly string _region;

    /// <summary>
    /// アクセスベースパス
    /// </summary>
    private readonly string _accessRoutePath;

    /// <summary>
    /// リージョンエンドポイント
    /// </summary>
    private readonly RegionEndpoint _regionEndpoint;

    /// <summary>
    /// コンストラクタ
    /// </summary>
    public S3Service()
    {
        _accessKey = "xxxxxxxxxxxxxxxxxx";
        _secretKey = "xxxxxxxxxxxxxxxxxx";
        _bucketName = "xxxxxxxxxxxxxxxxxx";
        _region = "ap-northeast-xxxx";
        _accessRoutePath = "xxxxxxxxxxxxxxxxxx";
        _regionEndpoint = RegionEndpoint.GetBySystemName(_region);
    }

    /// <summary>
    /// S3からファイルを取得する
    /// </summary>
    /// <typeparam name="T">デシリアライズしたいクラス</typeparam>
    /// <param name="fileName">ファイル名</param>
    /// <returns>デシリアライズ後のオブジェクト</returns>
    public async Task<T?> ReadObjectDataAsync<T>(string fileName)
    {
        // S3クライアントの設定
        var s3Client = new AmazonS3Client(_accessKey, _secretKey, _regionEndpoint);

        // JSONファイルのキーを生成
        var fileKey = $"{_accessRoutePath}/{fileName}";

        // S3からファイルを取得
        using (var fileStream = await ReadObjectDataAsync(s3Client, _bucketName, fileKey))
        {
            if (fileStream != null)
            {
                // JSONをデシリアライズしてオブジェクトに変換
                using (var sr = new StreamReader(fileStream))
                {
                    var jsonContent = await sr.ReadToEndAsync();
                    return JsonConvert.DeserializeObject<T>(jsonContent);
                }
            }
            else
            {
                return default;
            }
        }
    }

    /// <summary>
    /// S3からファイルを取得する
    /// </summary>
    /// <param name="client">S3クライアント</param>
    /// <param name="bucketName">バケット名</param>
    /// <param name="fileKey">ファイルキー</param>
    /// <returns>取得データ</returns>
    public static async Task<MemoryStream?> ReadObjectDataAsync(AmazonS3Client client, string bucketName, string fileKey)
    {
        try
        {
            GetObjectRequest request = new GetObjectRequest
            {
                BucketName = bucketName,
                Key = fileKey
            };

            using (GetObjectResponse response = await client.GetObjectAsync(request))
            using (Stream responseStream = response.ResponseStream)
            {
                var memoryStream = new MemoryStream();
                responseStream.CopyTo(memoryStream);
                memoryStream.Position = 0; // メモリストリームの位置をリセット
                return memoryStream;
            }
        }
        catch (AmazonS3Exception e)
        {
            Debug.WriteLine(e.Message);
            return null;
        }
        catch (Exception e)
        {
            Debug.WriteLine(e.Message);
            return null;
        }
    }
}

いくつかのセクションに分けて、説明していきたいと思います。

コンストラクタ


public S3Service()
{
    _accessKey = "xxxxxxxxxxxxxxxxxx";
    _secretKey = "xxxxxxxxxxxxxxxxxx";
    _bucketName = "xxxxxxxxxxxxxxxxxx";
    _region = "ap-northeast-xxxx";
    _accessRoutePath = "xxxxxxxxxxxxxxxxxx";
    _regionEndpoint = RegionEndpoint.GetBySystemName(_region);
}

コンストラクタでは、必要なアクセスキーやシークレットキー、バケット名、リージョン情報を初期化します。 リージョンエンドポイントは、RegionEndpoint.GetBySystemNameメソッドを使用して、リージョン情報を基に取得します。

S3オブジェクト読み込み その1


public async Task<T?> ReadObjectDataAsync<T>(string fileName)
{
    var s3Client = new AmazonS3Client(_accessKey, _secretKey, _regionEndpoint);
    var fileKey = $"{_accessRoutePath}/{fileName}";

    using (var fileStream = await ReadObjectDataAsync(s3Client, _bucketName, fileKey))
    {
        if (fileStream != null)
        {
            using (var sr = new StreamReader(fileStream))
            {
                var jsonContent = await sr.ReadToEndAsync();
                return JsonConvert.DeserializeObject<T>(jsonContent);
            }
        }
        else
        {
            return default;
        }
    }
}

このメソッドでは、指定されたファイル名のファイルをS3から取得し、その内容を指定されたクラスにデシリアライズして返します。 まず、S3クライアントであるAmazonS3Clientを作成し、バケットの場所を特定するためのfileKeyを生成します。

その後、次のセクションで説明するReadObjectDataAsyncメソッドを呼び出してファイルを取得し、JSONコンテンツをデシリアライズします。

S3オブジェクト読み込み その2


public static async Task<MemoryStream?> ReadObjectDataAsync(AmazonS3Client client, string bucketName, string fileKey)
{
    try
    {
        GetObjectRequest request = new GetObjectRequest
        {
            BucketName = bucketName,
            Key = fileKey
        };

        using (GetObjectResponse response = await client.GetObjectAsync(request))
        using (Stream responseStream = response.ResponseStream)
        {
            var memoryStream = new MemoryStream();
            responseStream.CopyTo(memoryStream);
            memoryStream.Position = 0; // メモリストリームの位置をリセット
            return memoryStream;
        }
    }
    catch (AmazonS3Exception e)
    {
        Debug.WriteLine(e.Message);
        return null;
    }
    catch (Exception e)
    {
        Debug.WriteLine(e.Message);
        return null;
    }
}

このメソッドは、S3クライアントのclientを使用して引数で指定されたbucketNamefileKeyからファイルを取得し、 その内容をメモリストリームにコピーして返却します。

例外は発生した場合は、デバッグ画面でエラーメッセージを出力するようにしています。 必要に応じて、ログを出力するように変更しても問題ありません。


まとめ

セクション画像

このS3Serviceクラスを使用することで、Blazorアプリケーションから簡単にAWS S3バケットにアクセスし、 ファイルを取得してデシリアライズすることができます。 是非AWS.S3を利用して、データの管理を行ってみてください。


ブログ内の記事で書かれているサンプルコードは、GitHubから確認する事ができます。 是非参考にしてみてください。

この本では、Blazorの基本から高度なテクニックまで、実際のプロジェクトに役立つ知識を網羅しています。 初心者から経験者まで、Blazorを扱うすべての開発者にとっての必読書です。 この記事の執筆者も参考にした「Blazor入門」で、あなたのBlazorスキルを飛躍的に向上させませんか?

合わせて読みたい

カード画像
ドラッグ&ドロップの実装サンプル

Blazorでドラッグ&ドロップを簡単に実装する方法を解説します。コード例を用いて、要素のドラッグ可能設定、イベントハンドラondragstartとondropの使用方法、リストの要素を交換する方法を説明します。視覚的なデモも含めて、実装のポイントを詳しく紹介します。

更新日:2024/06/06

カード画像
ページをリロードする

Blazorでページをリロードする方法について解説します。JavaScriptのlocation.reloadを利用する方法や、NavigationManager.NavigateToメソッドでforceLoadオプションを使ったリロード方法を紹介します。使い分けにより、ページの状態を適切に管理できます。

更新日:2024/08/29

An error has occurred. This application may no longer respond until reloaded. Reload 🗙