5

I have a Lambda function written in C# that is unsuccessfully attempting to upload an object to an S3 bucket. For testing purposes, I am converting the input string to a byte array and using that as the object contents. My handler function is defined below:

public void FunctionHandler(string input, ILambdaContext context)
{
    IAmazonS3 client = new AmazonS3Client(Amazon.RegionEndpoint.USEast1);

    byte[] bytes = new byte[input.Length * sizeof(char)];
    Buffer.BlockCopy(input.ToCharArray(), 0, bytes, 0, bytes.Length);

    using (MemoryStream ms = new MemoryStream())
    {
        foreach (Byte b in bytes)
        {
            ms.WriteByte(b);
        }

        PutObjectRequest request = new PutObjectRequest()
        {
            BucketName = "BUCKET_NAME",
            Key = "OBJECT_KEY",
            InputStream = ms
        };

        client.PutObjectAsync(request);
    }
}

The function runs without error, but the object is not written to S3. I feel that it might have something to do with the PutObjectAsync method, but I'm not positive. The IAmazonS3 interface includes a PutObject method, but when attempting to use that method I receive the following error:

'IAmazonS3' does not contain a definition for 'PutObject'

What is the best way to upload an object to an S3 bucket in a C# Lambda function?

2 Answers 2

10

This is the helper function I use to put S3 objects to S3, from a C# lambda function (and it works). You might be able to use this as a starting point for yours.

Not sure why you are converting your string to bytes, and in C#/Lambda you need to use the PutObjectAsync method, not the PutObject method:

 public static async Task<bool> PutS3Object(string bucket, string key, string content)
        {
            try
            {
                using (var client = new AmazonS3Client(Amazon.RegionEndpoint.USEast1))
                {
                    var request = new PutObjectRequest
                    {
                        BucketName = bucket,
                        Key = key,
                        ContentBody = content
                    };
                    var response = await client.PutObjectAsync(request);
                }
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception in PutS3Object:" + ex.Message);
                return false;
            }
        }
Sign up to request clarification or add additional context in comments.

3 Comments

Really the return should be return response.HttpStatusCode == HttpStatusCode.OK;
Not sure why you are converting your string to bytes - What do you mean ? since when working with strings is better than byte arrays ? base64 is 33% bigger. Care to explain ?
I was simply stating that I couldn't comment on his converting string to bytes part of his code - not taking an opinion one way or the other - but my working solution didn't rely on it so left it to him to decide if that was necessary or not and he could adapt as he saw fit.
2

You should apply await with the Async

await client.PutObjectAsync(request);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.