AWS Security ChangesHomeSearch

AWS code-library documentation change

Service: code-library · 2026-02-13 · Documentation low

File: code-library/latest/ug/s3_example_s3_Scenario_GettingStarted_section.md

Summary

Updated S3 .NET SDK example from v3 to v4, added interactive scenario mode with dependency injection, improved error handling, added non-interactive mode support, and implemented temporary file cleanup.

Security assessment

The changes focus on code modernization (dependency injection, async/await) and usability improvements (interactive/non-interactive modes). No security vulnerabilities are addressed, and no security-specific features are documented. The temporary file cleanup improves hygiene but doesn't address a specific security vulnerability.

Diff

diff --git a/code-library/latest/ug/s3_example_s3_Scenario_GettingStarted_section.md b/code-library/latest/ug/s3_example_s3_Scenario_GettingStarted_section.md
index a77e6b2c7..50a252532 100644
--- a//code-library/latest/ug/s3_example_s3_Scenario_GettingStarted_section.md
+++ b//code-library/latest/ug/s3_example_s3_Scenario_GettingStarted_section.md
@@ -27 +27 @@ The following code examples show how to:
-**SDK for .NET**
+**SDK for .NET (v4)**
@@ -32 +32,3 @@ The following code examples show how to:
-There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/dotnetv3/S3/S3_Basics#code-examples). 
+There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/dotnetv4/S3#code-examples). 
+
+Run an interactive scenario demonstrating Amazon S3 features.
@@ -37 +39,7 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-            public static async Task Main()
+        public static bool IsInteractive = true;
+        public static string BucketName = null!;
+        public static string TempFilePath = null!;
+        public static S3Wrapper _s3Wrapper = null!;
+        public static ILogger<S3_Basics> _logger = null!;
+    
+        public static async Task Main(string[] args)
@@ -39,8 +47,10 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                // Create an Amazon S3 client object. The constructor uses the
-                // default user installed on the system. To work with Amazon S3
-                // features in a different AWS Region, pass the AWS Region as a
-                // parameter to the client constructor.
-                IAmazonS3 client = new AmazonS3Client();
-                string bucketName = string.Empty;
-                string filePath = string.Empty;
-                string keyName = string.Empty;
+            // Set up dependency injection for the Amazon service.
+            using var host = Host.CreateDefaultBuilder(args)
+                .ConfigureServices((_, services) =>
+                    services.AddAWSService<IAmazonS3>()
+                        .AddTransient<S3Wrapper>()
+                        .AddLogging(builder => builder.AddConsole()))
+                .Build();
+    
+            _logger = LoggerFactory.Create(builder => builder.AddConsole())
+                .CreateLogger<S3_Basics>();
@@ -48 +58,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                var sepBar = new string('-', Console.WindowWidth);
+            _s3Wrapper = host.Services.GetRequiredService<S3Wrapper>();
+    
+            var sepBar = new string('-', 45);
@@ -60,0 +73,23 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+            await RunScenario(_s3Wrapper, _logger);
+    
+            Console.WriteLine(sepBar);
+            Console.WriteLine("The Amazon S3 scenario has successfully completed.");
+            Console.WriteLine(sepBar);
+        }
+    
+        /// <summary>
+        /// Run the S3 Basics scenario with injected dependencies.
+        /// </summary>
+        /// <param name="s3Wrapper">The S3 wrapper instance.</param>
+        /// <param name="scenarioLogger">The logger instance.</param>
+        /// <returns>A Task object.</returns>
+        public static async Task RunScenario(S3Wrapper s3Wrapper, ILogger<S3_Basics> scenarioLogger)
+        {
+            string bucketName = BucketName;
+            string filePath = TempFilePath;
+            string keyName = string.Empty;
+    
+            var sepBar = new string('-', 45);
+    
+            try
+            {
@@ -65,0 +101,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+                if (IsInteractive)
+                {
@@ -67,0 +105,5 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+                }
+                else
+                {
+                    Console.WriteLine($"Using bucket name: {bucketName}");
+                }
@@ -69 +111 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                var success = await S3Bucket.CreateBucketAsync(client, bucketName);
+                var success = await s3Wrapper.CreateBucketAsync(bucketName);
@@ -82,0 +125,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+                if (IsInteractive)
+                {
@@ -95,0 +140,18 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+                }
+                else
+                {
+                    // Use the public variable if set, otherwise create a temp file
+                    if (!string.IsNullOrEmpty(TempFilePath))
+                    {
+                        filePath = TempFilePath;
+                        Console.WriteLine($"Using provided test file: {filePath}");
+                    }
+                    else
+                    {
+                        // Create a temporary test file for non-interactive mode
+                        filePath = Path.GetTempFileName();
+                        var testContent = "This is a test file for S3 basics scenario.\nGenerated on: " + DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss UTC");
+                        await File.WriteAllTextAsync(filePath, testContent);
+                        Console.WriteLine($"Created temporary test file: {filePath}");
+                    }
+                }
@@ -100 +162 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                success = await S3Bucket.UploadFileAsync(client, bucketName, keyName, filePath);
+                success = await s3Wrapper.UploadFileAsync(bucketName, keyName, filePath);
@@ -111,3 +173,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                // Set the file path to an empty string to avoid overwriting the
-                // file we just uploaded to the bucket.
-                filePath = string.Empty;
+                // Set up download path
+                string downloadPath = string.Empty;
@@ -114,0 +176,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+                if (IsInteractive)
+                {
@@ -116 +179 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                while (string.IsNullOrEmpty(filePath))
+                    while (string.IsNullOrEmpty(downloadPath))
@@ -120 +183 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                    filePath = Console.ReadLine();
+                        downloadPath = Console.ReadLine();
@@ -122,2 +185,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                    // Confirm that the file exists on the local computer.
-                    if (File.Exists($"{filePath}\\{keyName}"))
+                        // Confirm that the file doesn't already exist on the local computer.
+                        if (File.Exists($"{downloadPath}\\{keyName}"))
@@ -126 +189,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                        filePath = string.Empty;
+                            downloadPath = string.Empty;
+                        }
@@ -128,0 +193,11 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+                else
+                {
+                    downloadPath = Path.GetTempPath();
+                    var downloadFile = Path.Combine(downloadPath, keyName);
+                    if (File.Exists(downloadFile))
+                    {
+                        File.Delete(downloadFile);
+                    }
+    
+                    Console.WriteLine($"Using download path: {downloadPath}");
+                }
@@ -131 +206 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                success = await S3Bucket.DownloadObjectFromBucketAsync(client, bucketName, keyName, filePath);
+                success = await s3Wrapper.DownloadObjectFromBucketAsync(bucketName, keyName, downloadPath);
@@ -144,0 +220,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+                if (IsInteractive)
+                {
@@ -150,2 +227,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    
-                while (string.IsNullOrEmpty(keyName))
+                }
+                else
@@ -153,3 +230,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                    // Get the name to give to the object once uploaded.
-                    Console.Write("Enter the name of the object to copy: ");
-                    keyName = Console.ReadLine();
+                    folderName = "test-folder";
+                    Console.WriteLine($"Using folder name: {folderName}");
@@ -158 +234 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                await S3Bucket.CopyObjectInBucketAsync(client, bucketName, keyName, folderName);
+                await s3Wrapper.CopyObjectInBucketAsync(bucketName, keyName, folderName);
@@ -161 +237 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                await S3Bucket.ListBucketContentsAsync(client, bucketName);
+                await s3Wrapper.ListBucketContentsAsync(bucketName);
@@ -164 +240,5 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                await S3Bucket.DeleteBucketContentsAsync(client, bucketName);
+                if (IsInteractive)
+                {
+                    Console.WriteLine("Press <Enter> when you are ready to delete the bucket contents.");
+                    _ = Console.ReadLine();
+                }
@@ -166,2 +246,15 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                // Deleting the bucket too quickly after deleting its contents will
-                // cause an error that the bucket isn't empty. So...
+                var deleteContentsSuccess = await s3Wrapper.DeleteBucketContentsAsync(bucketName);
+                if (deleteContentsSuccess)
+                {
+                    Console.WriteLine($"Successfully deleted contents of {bucketName}.\n");
+                }
+                else
+                {
+                    Console.WriteLine($"Sorry, could not delete contents of {bucketName}.\n");
+                }
+    
+                if (IsInteractive)
+                {
+                    // Deleting the bucket too quickly after separately deleting its contents can
+                    // cause an error that the bucket isn't empty. To delete contents and bucket in one
+                    // operation, use AmazonS3Util.DeleteS3BucketWithObjectsAsync
@@ -169,0 +263,7 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+                }
+                else
+                {
+                    // Add a small delay for non-interactive mode to ensure objects are fully deleted.
+                    Console.WriteLine("Waiting a moment for objects to be fully deleted...");
+                    await Task.Delay(2000);
+                }
@@ -172 +272,60 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                await S3Bucket.DeleteBucketAsync(client, bucketName);