O upload de formulário permite que aplicativos web façam upload de arquivos diretamente ao OSS por meio de formulários HTML padrão. Este tópico descreve como usar o C# SDK V2 para gerar informações, como assinaturas Post e políticas Post, e chamar o método HTTP POST para fazer upload de arquivos ao OSS.
Precauções
O código de exemplo deste tópico usa a região China (Hangzhou), com o ID
cn-hangzhou. Por padrão, o código usa o endpoint público. Para acessar o OSS a partir de outros produtos da Alibaba Cloud na mesma região, use o endpoint interno. Para mais informações sobre regiões e endpoints do OSS, consulte OSS regions and endpoints.O tamanho de um objeto enviado por upload de formulário não pode exceder 5 GB.
Código de exemplo
O código de exemplo a seguir demonstra o processo completo de upload de formulário. As principais etapas são:
Inicialize as configurações e os parâmetros: Defina a região, o bucket, a chave do objeto e o produto. Carregue a credencial de acesso das variáveis de ambiente e prepare o conteúdo a ser enviado.
Crie uma política Post: Defina o período de validade e as condições da requisição de upload.
Serialize e codifique a política: Serialize a política em uma string JSON e aplique a codificação Base64.
Gere uma chave de assinatura: Use o algoritmo HMAC-SHA256 para gerar uma chave inicial com base no AccessKeySecret. Em seguida, calcule o hash sequencial da data, região, produto e tipo de requisição para gerar a chave de assinatura final.
Construa o corpo da requisição: Crie um formulário multipart em conformidade com a especificação HTTP POST. Adicione a chave do objeto, a política codificada em Base64, a versão da assinatura, as informações de credencial, a data da requisição, a assinatura e os dados a serem enviados.
Crie e execute a requisição: Crie um cliente HTTP e envie uma requisição POST para o endpoint do OSS. Processe a resposta e exiba o código de status e as informações do cabeçalho de resposta.
using OSS = AlibabaCloud.OSS.V2; // Create an alias for Alibaba Cloud OSS SDK to simplify subsequent use.
using System.Globalization;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
var region = "cn-hangzhou"; // Required. Set the region where the bucket is located. This topic uses China (Hangzhou) as an example. Set the region to cn-hangzhou.
var bucket = "your bucket name"; // Required. The name of the bucket.
var key = "your object key"; // Required. The name of the destination object to upload.
var product = "oss"; // Required. The product identifier for OSS.
// Convert a byte array to a hexadecimal string.
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();
}
// Add double quotation marks to a string.
static string quote(string value)
{
return $"\"{value}\"";
}
// Load the default configurations of the OSS SDK. This configuration automatically reads credential information (such as AccessKey) from environment variables.
var cfg = OSS.Configuration.LoadDefault();
// Explicitly set to use environment variables to obtain credentials for identity verification (format: OSS_ACCESS_KEY_ID, OSS_ACCESS_KEY_SECRET).
var credentialsProvider = new OSS.Credentials.EnvironmentVariableCredentialsProvider();
var credentials = credentialsProvider.GetCredentials();
// The content to upload.
var content = "hello oss";
// Construct the Policy (upload policy).
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); // The signature is valid for 1 hour.
// Construct credential information.
var credentialInfo = $"{credentials.AccessKeyId}/{date}/{region}/{product}/aliyun_v4_request";
// Construct the Policy JSON.
var policyMap = new Dictionary<string, Object>()
{
// Set the expiration time of the policy.
{ "expiration",
expiration.ToUniversalTime().ToString("yyyy-MM-dd'T'HH:mm:ss.000'Z'", CultureInfo.InvariantCulture)
},
// Set the upload conditions.
{ "conditions", new Object[]{
// The object must be uploaded to the specified bucket.
new Dictionary<string, string>() {{ "bucket", bucket } },
// Specify the signature version.
new Dictionary<string, string>() {{ "x-oss-signature-version", "OSS4-HMAC-SHA256" } },
// Specify the credential information.
new Dictionary<string, string>() {{ "x-oss-credential", credentialInfo } },
// Specify the request time.
new Dictionary<string, string>() {{ "x-oss-date", dateTime } },
// Limit the range of the upload content length.
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" } },
}
},
};
// Serialize to a JSON string.
var policy = JsonSerializer.Serialize(policyMap);
// Perform Base64 encoding on the Policy.
var stringToSign = Convert.ToBase64String(Encoding.UTF8.GetBytes(policy));
// Generate the signature key.
using var kha = new HMACSHA256();
// The initial key is generated from the AccessKeySecret.
var ksecret = Encoding.UTF8.GetBytes("aliyun_v4" + credentials.AccessKeySecret);
// Generate the signature key level by level.
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"));
// Calculate the final signature.
kha.Key = signingKey;
var signature = ToHexString(kha.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)), true);
// Construct the multipart form data.
using var formData = new MultipartFormDataContent();
// Handle the quotation mark issue for the boundary.
var boundary = formData.Headers.ContentType!.Parameters.ElementAt(0).Value!;
formData.Headers.ContentType.Parameters.ElementAt(0).Value = boundary.Trim('"');
// Add a form field - the object key name.
formData.Add(new ByteArrayContent(Encoding.UTF8.GetBytes(key)), quote("key"));
// You can add metadata.
//formData.Add(new ByteArrayContent(Encoding.UTF8.GetBytes(value)), quote("x-oss-"));
// Add the Policy.
formData.Add(new ByteArrayContent(Encoding.UTF8.GetBytes(stringToSign)), quote("policy"));
// Add signature-related information.
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"));
// Add the content to be uploaded.
formData.Add(new ByteArrayContent(Encoding.UTF8.GetBytes(content)), quote("file"));
// Send a POST request to OSS.
using var hc = new HttpClient();
var result = await hc.PostAsync($"http://{bucket}.oss-{region}.aliyuncs.com/", formData);
// Print the upload result.
Console.WriteLine("PostObject done"); // Indicates that the operation is complete.
Console.WriteLine($"StatusCode: {result.StatusCode}"); // HTTP status code.
Console.WriteLine("Response Headers:"); // Response header information.
result.Headers.ToList().ForEach(x => Console.WriteLine(x.Key + " : " + String.Join(",", x.Value.ToList()))); // Traverse and print all response headers.
Referências
Para acessar o código de exemplo completo de upload de formulário, consulte postObject.cs.