使用 適用於 .NET 的 SDK (v4) 的 Amazon S3 範例 - AWS SDK 程式碼範例

文件 AWS 開發套件範例 GitHub 儲存庫中有更多可用的 AWS SDK 範例

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

使用 適用於 .NET 的 SDK (v4) 的 Amazon S3 範例

下列程式碼範例示範如何使用 適用於 .NET 的 AWS SDK (v4) 搭配 Amazon S3 執行動作和實作常見案例。

Actions 是大型程式的程式碼摘錄,必須在內容中執行。雖然動作會告訴您如何呼叫個別服務函數,但您可以在其相關情境中查看內容中的動作。

案例是向您展示如何呼叫服務中的多個函數或與其他 AWS 服務組合來完成特定任務的程式碼範例。

每個範例都包含完整原始程式碼的連結,您可以在其中找到如何在內容中設定和執行程式碼的指示。

動作

以下程式碼範例顯示如何使用 CreatePresignedPost

適用於 .NET 的 SDK (v4)
注意

GitHub 上提供更多範例。尋找完整範例,並了解如何在 AWS 程式碼範例儲存庫中設定和執行。

建立預先簽章的 POST URL。

/// <summary> /// Create a presigned POST URL with conditions. /// </summary> /// <param name="s3Client">The Amazon S3 client.</param> /// <param name="bucketName">The name of the bucket.</param> /// <param name="objectKey">The object key (path) where the uploaded file will be stored.</param> /// <param name="expires">When the presigned URL expires.</param> /// <param name="fields">Dictionary of fields to add to the form.</param> /// <param name="conditions">List of conditions to apply.</param> /// <returns>A CreatePresignedPostResponse object with URL and form fields.</returns> public async Task<CreatePresignedPostResponse> CreatePresignedPostAsync( IAmazonS3 s3Client, string bucketName, string objectKey, DateTime expires, Dictionary<string, string>? fields = null, List<S3PostCondition>? conditions = null) { var request = new CreatePresignedPostRequest { BucketName = bucketName, Key = objectKey, Expires = expires }; // Add custom fields if provided if (fields != null) { foreach (var field in fields) { request.Fields.Add(field.Key, field.Value); } } // Add conditions if provided if (conditions != null) { foreach (var condition in conditions) { request.Conditions.Add(condition); } } return await s3Client.CreatePresignedPostAsync(request); }
  • 如需 API 詳細資訊,請參閱適用於 .NET 的 AWS SDK 《 API 參考》中的 CreatePresignedPost

案例

下列程式碼範例示範如何建立 Amazon S3 的預先簽章 URL 並上傳物件。

適用於 .NET 的 SDK (v4)
注意

GitHub 上提供更多範例。尋找完整範例,並了解如何在 AWS 程式碼範例儲存庫中設定和執行。

建立並使用預先簽章的 POST URLs 進行直接瀏覽器上傳。

/// <summary> /// Scenario demonstrating the complete workflow for presigned POST URLs: /// 1. Create an S3 bucket /// 2. Create a presigned POST URL /// 3. Upload a file using the presigned POST URL /// 4. Clean up resources /// </summary> public class CreatePresignedPostBasics { public static ILogger<CreatePresignedPostBasics> _logger = null!; public static S3Wrapper _s3Wrapper = null!; public static UiMethods _uiMethods = null!; public static IHttpClientFactory _httpClientFactory = null!; public static bool _isInteractive = true; public static string? _bucketName; public static string? _objectKey; /// <summary> /// Set up the services and logging. /// </summary> /// <param name="host">The IHost instance.</param> public static void SetUpServices(IHost host) { var loggerFactory = LoggerFactory.Create(builder => { builder.AddConsole(); }); _logger = new Logger<CreatePresignedPostBasics>(loggerFactory); _s3Wrapper = host.Services.GetRequiredService<S3Wrapper>(); _httpClientFactory = host.Services.GetRequiredService<IHttpClientFactory>(); _uiMethods = new UiMethods(); } /// <summary> /// Perform the actions defined for the Amazon S3 Presigned POST scenario. /// </summary> /// <param name="args">Command line arguments.</param> /// <returns>A Task object.</returns> public static async Task Main(string[] args) { _isInteractive = !args.Contains("--non-interactive"); // Set up dependency injection for Amazon S3 using var host = Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder(args) .ConfigureServices((_, services) => services.AddAWSService<IAmazonS3>() .AddTransient<S3Wrapper>() .AddHttpClient() ) .Build(); SetUpServices(host); try { // Display overview _uiMethods.DisplayOverview(); _uiMethods.PressEnter(_isInteractive); // Step 1: Create bucket await CreateBucketAsync(); _uiMethods.PressEnter(_isInteractive); // Step 2: Create presigned URL _uiMethods.DisplayTitle("Step 2: Create presigned POST URL"); var response = await CreatePresignedPostAsync(); _uiMethods.PressEnter(_isInteractive); // Step 3: Display URL and fields _uiMethods.DisplayTitle("Step 3: Presigned POST URL details"); DisplayPresignedPostFields(response); _uiMethods.PressEnter(_isInteractive); // Step 4: Upload file _uiMethods.DisplayTitle("Step 4: Upload test file using presigned POST URL"); await UploadFileAsync(response); _uiMethods.PressEnter(_isInteractive); // Step 5: Verify file exists await VerifyFileExistsAsync(); _uiMethods.PressEnter(_isInteractive); // Step 6: Cleanup _uiMethods.DisplayTitle("Step 6: Clean up resources"); await CleanupAsync(); _uiMethods.DisplayTitle("S3 Presigned POST Scenario completed successfully!"); _uiMethods.PressEnter(_isInteractive); } catch (Exception ex) { _logger.LogError(ex, "Error in scenario"); Console.WriteLine($"Error: {ex.Message}"); // Attempt cleanup if there was an error if (!string.IsNullOrEmpty(_bucketName)) { _uiMethods.DisplayTitle("Cleaning up resources after error"); await _s3Wrapper.DeleteBucketAsync(_bucketName); Console.WriteLine($"Cleaned up bucket: {_bucketName}"); } } } /// <summary> /// Create an S3 bucket for the scenario. /// </summary> private static async Task CreateBucketAsync() { _uiMethods.DisplayTitle("Step 1: Create an S3 bucket"); // Generate a default bucket name for the scenario var defaultBucketName = $"presigned-post-demo-{DateTime.Now:yyyyMMddHHmmss}".ToLower(); // Prompt user for bucket name or use default in non-interactive mode _bucketName = _uiMethods.GetUserInput( $"Enter S3 bucket name (or press Enter for '{defaultBucketName}'): ", defaultBucketName, _isInteractive); // Basic validation to ensure bucket name is not empty if (string.IsNullOrWhiteSpace(_bucketName)) { _bucketName = defaultBucketName; } Console.WriteLine($"Creating bucket: {_bucketName}"); await _s3Wrapper.CreateBucketAsync(_bucketName); Console.WriteLine($"Successfully created bucket: {_bucketName}"); } /// <summary> /// Create a presigned POST URL. /// </summary> private static async Task<CreatePresignedPostResponse> CreatePresignedPostAsync() { _objectKey = "example-upload.txt"; var expiration = DateTime.UtcNow.AddMinutes(10); // Short expiration for the demo Console.WriteLine($"Creating presigned POST URL for {_bucketName}/{_objectKey}"); Console.WriteLine($"Expiration: {expiration} UTC"); var s3Client = _s3Wrapper.GetS3Client(); var response = await _s3Wrapper.CreatePresignedPostAsync( s3Client, _bucketName!, _objectKey, expiration); Console.WriteLine("Successfully created presigned POST URL"); return response; } /// <summary> /// Upload a file using the presigned POST URL. /// </summary> private static async Task UploadFileAsync(CreatePresignedPostResponse response) { // Create a temporary test file to upload string testFilePath = Path.GetTempFileName(); string testContent = "This is a test file for the S3 presigned POST scenario."; await File.WriteAllTextAsync(testFilePath, testContent); Console.WriteLine($"Created test file at: {testFilePath}"); // Upload the file using the presigned POST URL Console.WriteLine("\nUploading file using the presigned POST URL..."); var uploadResult = await UploadFileWithPresignedPostAsync(response, testFilePath); // Display the upload result if (uploadResult.Success) { Console.WriteLine($"Upload successful! Status code: {uploadResult.StatusCode}"); } else { Console.WriteLine($"Upload failed with status code: {uploadResult.StatusCode}"); Console.WriteLine($"Error: {uploadResult.Response}"); throw new Exception("File upload failed"); } // Clean up the temporary file File.Delete(testFilePath); Console.WriteLine("Temporary file deleted"); } /// <summary> /// Helper method to upload a file using a presigned POST URL. /// </summary> private static async Task<(bool Success, HttpStatusCode StatusCode, string Response)> UploadFileWithPresignedPostAsync( CreatePresignedPostResponse response, string filePath) { try { _logger.LogInformation("Uploading file {filePath} using presigned POST URL", filePath); using var httpClient = _httpClientFactory.CreateClient(); using var formContent = new MultipartFormDataContent(); // Add all the fields from the presigned POST response foreach (var field in response.Fields) { formContent.Add(new StringContent(field.Value), field.Key); } // Add the file content var fileStream = File.OpenRead(filePath); var fileName = Path.GetFileName(filePath); var fileContent = new StreamContent(fileStream); fileContent.Headers.ContentType = new MediaTypeHeaderValue("text/plain"); formContent.Add(fileContent, "file", fileName); // Send the POST request var httpResponse = await httpClient.PostAsync(response.Url, formContent); var responseContent = await httpResponse.Content.ReadAsStringAsync(); // Log and return the result _logger.LogInformation("Upload completed with status code {statusCode}", httpResponse.StatusCode); return (httpResponse.IsSuccessStatusCode, httpResponse.StatusCode, responseContent); } catch (Exception ex) { _logger.LogError(ex, "Error uploading file"); return (false, HttpStatusCode.InternalServerError, ex.Message); } } /// <summary> /// Verify that the uploaded file exists in the S3 bucket. /// </summary> private static async Task VerifyFileExistsAsync() { _uiMethods.DisplayTitle("Step 5: Verify uploaded file exists"); Console.WriteLine($"Checking if file exists at {_bucketName}/{_objectKey}..."); try { var metadata = await _s3Wrapper.GetObjectMetadataAsync(_bucketName!, _objectKey!); Console.WriteLine($"File verification successful! File exists in the bucket."); Console.WriteLine($"File size: {metadata.ContentLength} bytes"); Console.WriteLine($"File type: {metadata.Headers.ContentType}"); Console.WriteLine($"Last modified: {metadata.LastModified}"); } catch (AmazonS3Exception ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound) { Console.WriteLine($"Error: File was not found in the bucket."); throw; } } private static void DisplayPresignedPostFields(CreatePresignedPostResponse response) { Console.WriteLine($"Presigned POST URL: {response.Url}"); Console.WriteLine("Form fields to include:"); foreach (var field in response.Fields) { Console.WriteLine($" {field.Key}: {field.Value}"); } } /// <summary> /// Clean up resources created by the scenario. /// </summary> private static async Task CleanupAsync() { if (!string.IsNullOrEmpty(_bucketName)) { Console.WriteLine($"Deleting bucket {_bucketName} and its contents..."); bool result = await _s3Wrapper.DeleteBucketAsync(_bucketName); if (result) { Console.WriteLine("Bucket deleted successfully"); } else { Console.WriteLine("Failed to delete bucket - it may have been already deleted"); } } } }