Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Amazon S3 Creating Folder through .NET SDK vs through Management Console

I'm trying to determine if a folder exists on my Amazon S3 Bucket and if it doesn't I want to create it.

At the moment I can create the folder using the .NET SDK as follows:

        public void CreateFolder(string bucketName, string folderName)
    {
        var folderKey = folderName + "/"; //end the folder name with "/"

        var request = new PutObjectRequest();

        request.WithBucketName(bucketName);

        request.StorageClass = S3StorageClass.Standard;
        request.ServerSideEncryptionMethod = ServerSideEncryptionMethod.None;

        //request.CannedACL = S3CannedACL.BucketOwnerFullControl;

        request.WithKey(folderKey);

        request.WithContentBody(string.Empty);

        S3Response response = m_S3Client.PutObject(request);

    }

Now when I try to see if the folder exists using this code:

        public bool DoesFolderExist(string key, string bucketName)
    {
        try
        {
            S3Response response = m_S3Client.GetObjectMetadata(new GetObjectMetadataRequest()
               .WithBucketName(bucketName)
               .WithKey(key));

            return true;
        }
        catch (Amazon.S3.AmazonS3Exception ex)
        {
            if (ex.StatusCode == System.Net.HttpStatusCode.NotFound)
                return false;

            //status wasn't not found, so throw the exception
            throw;
        }
    }

It cannot find the folder. The strange thing is if I create the folder using the AWS Management Console, the 'DoesFolderExist' method can see it.

I'm not sure if it's an ACL/IAM thing but am not sure how to resolve this.

like image 714
Webcognoscere Avatar asked Mar 30 '12 14:03

Webcognoscere


1 Answers

Your code actually works for me, but there are a few things you need to be aware off.

As I understand it, Amazon S3 does not have a concept of folders, but individual clients may display the S3 objects as if they did. So if you create an object called A/B , then the client may display it as if it was an object called B inside a folder called A. This is intuitive and seems to have become a standard, but simulating an empty folder does not appear to have a standard.

For example, I used your method to create a folder called Test, then actually end up creating an object called Test/. But I created a folder called Test2 in AWS Explorer (ie the addon to Visual Studio) and it ended up creating an object called Test2/Test2_$folder$ (AWS Explorer will display both Test and Test2 as folders)

Once of the things that this means is that you don't need to create the 'folder' before you can use it, which may mean that you don't need a DoesFolderExist method.

As I mention I tried your code and it works and finds the Test folder it created, but the key had to be tweaked to find the folder created by AWS Explorer , ie

DoesFolderExist("Test/"               , bucketName);  // Returns true
DoesFolderExist("Test2/"              , bucketName);  // Returns false
DoesFolderExist("Test2/Test2_$folder$", bucketName);  // Returns true

So if you do still want to have a DoesFolderExist method, then it might be safer to just look for any objects that start with folderName + "/" , ie something like

ListObjectsRequest request = new ListObjectsRequest();
request.BucketName = bucketName ;
request.WithPrefix(folderName + "/");
request.MaxKeys = 1;

using (ListObjectsResponse response = m_S3Client.ListObjects(request))
{
    return (response.S3Objects.Count > 0);
}
like image 105
sgmoore Avatar answered Sep 20 '22 06:09

sgmoore