前言
最近在與第三方做串接時,有個需求是要將圖片存起來放在 Application Server 上,與同事討論建議將圖片放在AWS S3 上,多年前有微軟剛推出 Azure 時有接觸過一些,但這幾年隨著年紀增長早已忘光光,這篇簡單紀錄 C# 透過 AWS SDK 將圖片上傳到 AWS S3 上的步驟與要注意的細節
AWS S3
Amazon Simple Storage Service 功能簡稱 S3,是Amazon的物件儲存服務,主要提供使用者存放 Data 像是 html, css, js...等靜態檔案,上傳前需要建立儲存體 (Buckets) 來存放需要放在的物件,接著透過 AWS Manager Console 的後台服務上傳物件到雲端上,使用者就可以透過 S3 的服務讀取到上傳的資料,如下圖所示
安裝 AWS SDK
除了可以透過 AWS Manager Console 後台上傳檔案,AWS 也提供 SDK 讓開發者可以透過 API 來上傳儲存的物件,在 .NET 有兩種方式可以安裝此套件
1. 可以到 nuget 主控台 輸入下列指令下載 AWS SDK 套件
Install-Package AWSSDK -Version 2.3.55.2
2. 到 nuget 管理員輸入 AWSSDK 直接下載
設定 Config Key
在 Application Config 中設定 AccessKey , SecretKey
使用 AWS SDK 上傳物件到 S3
參考 開發人員指南 上傳 Code 如下
using System;
using System.Threading.Tasks;
using Amazon.S3;
using Amazon.S3.Transfer;
using Amazon;
using Amazon.S3.Model;
namespace AWS
{
class blog
{
private const string bucketName = "your bucketName";
private const string keyName = "Test.png";
private const string filePath = @"D:\Test.png";
private static readonly RegionEndpoint bucketRegion = RegionEndpoint.APNortheast1;
private static IAmazonS3 s3Client;
static void Main(string[] args)
{
s3Client = new AmazonS3Client(bucketRegion);
try
{
PutObjectRequest ObjectRequest = new PutObjectRequest
{
BucketName = bucketName,
FilePath = filePath,
Key = keyName,
CannedACL = S3CannedACL.PublicRead
};
// upload object
PutObjectResponse myResponse = s3Client.PutObject(ObjectRequest);
}
catch (AmazonS3Exception e)
{
Console.WriteLine("Error encountered on server. Message:'{0}' when writing an object", e.Message);
}
catch (Exception e)
{
Console.WriteLine("Unknown encountered on server. Message:'{0}' when writing an object", e.Message);
}
}
}
}
程式說明 :
- Line 12 : 要上傳到的 bucket Name 儲存體
- Line 13 : 要上傳到的位置 + 檔名 , 舉例 : 可以透過目錄區分物件 public / test / test.jpg
- Line 14 : 上傳物件路徑
- Line 15 : 定義 RegionEndpoint , 在一開始建立 bucket 會設定機房的位置 (參考備註)
- Line 20 : 初始化 s3Client 物件 透過建構子定義 Endpoint
- Line 24 : 初始化要上傳的物件 putObjectRequest,設定要上傳到的 bucketName 物件路徑 與 設定此物件為公開 (非必要)
- Line 24 : 使用 putObject 方法上傳物件
使用 AWS SDK 上傳物件到 S3 (非同步)
如果在開發上是有非同步的需求,可以參考下面
using System;
using System.Threading.Tasks;
using Amazon.S3;
using Amazon.S3.Transfer;
using Amazon;
namespace AWS
{
class blog
{
private const string bucketName = "urbucketName";
private const string filePath = @"D:\Test.png";
// Specify your bucket region (an example region is shown).
private static readonly RegionEndpoint bucketRegion = RegionEndpoint.APNortheast1;
private static IAmazonS3 s3Client;
static void Main(string[] args)
{
s3Client = new AmazonS3Client(bucketRegion);
UploadFileAsync().Wait();
}
private static async Task UploadFileAsync()
{
try
{
var fileTransferUtility = new TransferUtility(s3Client);
await fileTransferUtility.UploadAsync(filePath, bucketName);
Console.WriteLine("上傳完成");
}
catch (AmazonS3Exception e)
{
Console.WriteLine("Error encountered on server. Message:'{0}' when writing an object", e.Message);
}
catch (Exception e)
{
Console.WriteLine("Unknown encountered on server. Message:'{0}' when writing an object", e.Message);
}
}
}
}
程式說明 :
- Line 27 : 初始化 TransferUtility 物件 透過建構子定義 Endpoint
- Line 28 : 透過 TransferUtility 的 UploadAsync 方法上傳物件到 S3 上
補充
在定義 BucketRegion 需特別注意要指定到你一開始建立的機房位置,如果指定錯誤的話會出現
Error encountered on server. Message:'The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint.' when writing an object ?
建立位置與對應 EndPoint 可以參考官方 AWS Regions and Endpoints 說明,避免踩雷 XDDD
參考
Amazon S3 Features
Upload a File to an S3 Bucket Using the AWS SDK for .NET (High-Level API)
使用AWS SDK for .NET
Build a Serverless Web Application