フォームアップロードを使用すると、Web アプリケーションは標準の HTML フォームを使用して OSS にファイルを直接アップロードできます。このトピックでは、C# SDK V2 を使用して Post 署名や Post ポリシーなどの情報を生成し、HTTP POST メソッドを呼び出して OSS にファイルをアップロードする方法について説明します。
注意事項
このトピックのサンプルコードでは、中国 (杭州) リージョン ID である
cn-hangzhouを例として使用します。デフォルトでは、パブリックエンドポイントが使用されます。同じリージョン内の他の Alibaba Cloud プロダクトから OSS にアクセスする場合は、内部エンドポイントを使用します。詳細については、「OSS のリージョンとエンドポイント」をご参照ください。フォームアップロードを使用してアップロードされるオブジェクトのサイズは 5 GB を超えることはできません。
サンプルコード
次のサンプルコードは、完全なフォームアップロードプロセスを示しています。主なステップは次のとおりです。
構成とパラメーターの初期化: リージョン、バケット、オブジェクトキー、プロダクトを設定します。環境変数からアクセス資格情報を読み込み、アップロードするコンテンツを準備します。
Post ポリシーの作成: アップロードリクエストの有効期間と条件を定義します。
ポリシーのシリアル化とエンコード: ポリシーを JSON 文字列にシリアル化し、Base64 エンコーディングを実行します。
署名キーの生成: HMAC-SHA256 アルゴリズムを使用して、AccessKeySecret に基づいて初期キーを生成します。次に、日付、リージョン、プロダクト、リクエストタイプを順次ハッシュ化して、最終的な署名キーを生成します。
リクエストボディの構築: HTTP POST 仕様に準拠したマルチパートフォームデータを作成します。オブジェクトキー、Base64 エンコードされたポリシー、署名バージョン、資格情報、リクエスト日、署名、およびアップロードするデータを追加します。
リクエストの作成と実行: HTTP クライアントを作成し、OSS エンドポイントに POST リクエストを送信します。応答を処理し、ステータスコードと応答ヘッダー情報を出力します。
using OSS = AlibabaCloud.OSS.V2; // Alibaba Cloud OSS SDK のエイリアスを作成して、後続の使用を簡素化します。
using System.Globalization;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
var region = "cn-hangzhou"; // 必須。バケットが配置されているリージョンを設定します。このトピックでは、中国 (杭州) を例として使用します。リージョンを cn-hangzhou に設定します。
var bucket = "your bucket name"; // 必須。バケットの名前。
var key = "your object key"; // 必須。アップロード先のオブジェクトの名前。
var product = "oss"; // 必須。OSS のプロダクト識別子。
// バイト配列を 16 進数の文字列に変換します。
static string ToHexString(byte[] data, bool lowercase)
{
var sb = new StringBuilder();
for (var i = 0; i < data.Length; i++) sb.Append(data[i].ToString(lowercase ? "x2" : "X2"));
return sb.ToString();
}
// 文字列に二重引用符を追加します。
static string quote(string value)
{
return $"\"{value}\"";
}
// OSS SDK のデフォルト構成を読み込みます。この構成は、環境変数から資格情報 (AccessKey など) を自動的に読み取ります。
var cfg = OSS.Configuration.LoadDefault();
// 環境変数を使用して ID 検証用の資格情報を取得するように明示的に設定します (フォーマット: OSS_ACCESS_KEY_ID、OSS_ACCESS_KEY_SECRET)。
var credentialsProvider = new OSS.Credentials.EnvironmentVariableCredentialsProvider();
var credentials = credentialsProvider.GetCredentials();
// アップロードするコンテンツ。
var content = "hello oss";
// ポリシー (アップロードポリシー) を構築します。
var utcTime = DateTime.UtcNow;
var date = utcTime.ToUniversalTime().ToString("yyyyMMdd", CultureInfo.InvariantCulture);
var dateTime = utcTime.ToUniversalTime().ToString("yyyyMMdd'T'HHmmss'Z'", CultureInfo.InvariantCulture);
var expiration = utcTime.AddHours(1); // 署名は 1 時間有効です。
// 資格情報を構築します。
var credentialInfo = $"{credentials.AccessKeyId}/{date}/{region}/{product}/aliyun_v4_request";
// ポリシー JSON を構築します。
var policyMap = new Dictionary<string, Object>()
{
// ポリシーの有効期限を設定します。
{ "expiration",
expiration.ToUniversalTime().ToString("yyyy-MM-dd'T'HH:mm:ss.000'Z'", CultureInfo.InvariantCulture)
},
// アップロード条件を設定します。
{ "conditions", new Object[]{
// オブジェクトは指定されたバケットにアップロードする必要があります。
new Dictionary<string, string>() {{ "bucket", bucket } },
// 署名バージョンを指定します。
new Dictionary<string, string>() {{ "x-oss-signature-version", "OSS4-HMAC-SHA256" } },
// 資格情報を指定します。
new Dictionary<string, string>() {{ "x-oss-credential", credentialInfo } },
// リクエスト時刻を指定します。
new Dictionary<string, string>() {{ "x-oss-date", dateTime } },
// アップロードコンテンツの長さの範囲を制限します。
new Object[]{"content-length-range", 1, 1024 },
//new Object[]{"eq", "$success_action_status", "201"},
//new Object[]{"starts-with", "$key", "user/eric/"},
//new Object[]{"in", "$content-type", new string[]{"image/jpg", "image/png"}},
//new Object[]{ "not-in", "$cache-control", new string[]{ "no-cache" } },
}
},
};
// JSON 文字列にシリアル化します。
var policy = JsonSerializer.Serialize(policyMap);
// ポリシーに対して Base64 エンコーディングを実行します。
var stringToSign = Convert.ToBase64String(Encoding.UTF8.GetBytes(policy));
// 署名キーを生成します。
using var kha = new HMACSHA256();
// 初期キーは AccessKeySecret から生成されます。
var ksecret = Encoding.UTF8.GetBytes("aliyun_v4" + credentials.AccessKeySecret);
// 署名キーを段階的に生成します。
kha.Key = ksecret;
var hashDate = kha.ComputeHash(Encoding.UTF8.GetBytes(date));
kha.Key = hashDate;
var hashRegion = kha.ComputeHash(Encoding.UTF8.GetBytes(region));
kha.Key = hashRegion;
var hashProduct = kha.ComputeHash(Encoding.UTF8.GetBytes(product));
kha.Key = hashProduct;
var signingKey = kha.ComputeHash(Encoding.UTF8.GetBytes("aliyun_v4_request"));
// 最終的な署名を計算します。
kha.Key = signingKey;
var signature = ToHexString(kha.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)), true);
// マルチパートフォームデータを構築します。
using var formData = new MultipartFormDataContent();
// 境界線の引用符の問題を処理します。
var boundary = formData.Headers.ContentType!.Parameters.ElementAt(0).Value!;
formData.Headers.ContentType.Parameters.ElementAt(0).Value = boundary.Trim('"');
// フォームフィールドを追加します - オブジェクトキー名。
formData.Add(new ByteArrayContent(Encoding.UTF8.GetBytes(key)), quote("key"));
// メタデータを追加できます。
//formData.Add(new ByteArrayContent(Encoding.UTF8.GetBytes(value)), quote("x-oss-"));
// ポリシーを追加します。
formData.Add(new ByteArrayContent(Encoding.UTF8.GetBytes(stringToSign)), quote("policy"));
// 署名関連情報を追加します。
formData.Add(new ByteArrayContent(Encoding.UTF8.GetBytes("OSS4-HMAC-SHA256")), quote("x-oss-signature-version"));
formData.Add(new ByteArrayContent(Encoding.UTF8.GetBytes(credentialInfo)), quote("x-oss-credential"));
formData.Add(new ByteArrayContent(Encoding.UTF8.GetBytes(dateTime)), quote("x-oss-date"));
formData.Add(new ByteArrayContent(Encoding.UTF8.GetBytes(signature)), quote("x-oss-signature"));
// アップロードするコンテンツを追加します。
formData.Add(new ByteArrayContent(Encoding.UTF8.GetBytes(content)), quote("file"));
// OSS に POST リクエストを送信します。
using var hc = new HttpClient();
var result = await hc.PostAsync($"http://{bucket}.oss-{region}.aliyuncs.com/", formData);
// アップロード結果を出力します。
Console.WriteLine("PostObject done"); // 操作が完了したことを示します。
Console.WriteLine($"StatusCode: {result.StatusCode}"); // HTTP ステータスコード。
Console.WriteLine("Response Headers:"); // 応答ヘッダー情報。
result.Headers.ToList().ForEach(x => Console.WriteLine(x.Key + " : " + String.Join(",", x.Value.ToList()))); // すべての応答ヘッダーを走査して出力します。参考
フォームアップロードの完全なサンプルコードについては、「postObject.cs」をご参照ください。