すべてのプロダクト
Search
ドキュメントセンター

Object Storage Service:フォームアップロード (C# SDK V2)

最終更新日:Nov 09, 2025

フォームアップロードを使用すると、Web アプリケーションは標準の HTML フォームを使用して OSS にファイルを直接アップロードできます。このトピックでは、C# SDK V2 を使用して Post 署名や Post ポリシーなどの情報を生成し、HTTP POST メソッドを呼び出して OSS にファイルをアップロードする方法について説明します。

注意事項

  • このトピックのサンプルコードでは、中国 (杭州) リージョン ID である cn-hangzhou を例として使用します。デフォルトでは、パブリックエンドポイントが使用されます。同じリージョン内の他の Alibaba Cloud プロダクトから OSS にアクセスする場合は、内部エンドポイントを使用します。詳細については、「OSS のリージョンとエンドポイント」をご参照ください。

  • フォームアップロードを使用してアップロードされるオブジェクトのサイズは 5 GB を超えることはできません。

サンプルコード

次のサンプルコードは、完全なフォームアップロードプロセスを示しています。主なステップは次のとおりです。

  1. 構成とパラメーターの初期化: リージョン、バケット、オブジェクトキー、プロダクトを設定します。環境変数からアクセス資格情報を読み込み、アップロードするコンテンツを準備します。

  2. Post ポリシーの作成: アップロードリクエストの有効期間と条件を定義します。

  3. ポリシーのシリアル化とエンコード: ポリシーを JSON 文字列にシリアル化し、Base64 エンコーディングを実行します。

  4. 署名キーの生成: HMAC-SHA256 アルゴリズムを使用して、AccessKeySecret に基づいて初期キーを生成します。次に、日付、リージョン、プロダクト、リクエストタイプを順次ハッシュ化して、最終的な署名キーを生成します。

  5. リクエストボディの構築: HTTP POST 仕様に準拠したマルチパートフォームデータを作成します。オブジェクトキー、Base64 エンコードされたポリシー、署名バージョン、資格情報、リクエスト日、署名、およびアップロードするデータを追加します。

  6. リクエストの作成と実行: 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」をご参照ください。