You can do both with the custom uploadstreamprovider code I suggested here: http://krystalware.com/forums/yaf_postst1562_How-do-I-rename-a-file-before-uploading-it.aspx.
To specify the folder name, just return it as part of the object name you return from GetObjectName (for example, returning "folder/file.ext"). S3 doesn't have the concept of folders per se, so it doesn't need to create them -- it just allows you to delineate files based on the "/" character in their name.
Changing the bucket name is a bit more complex, because the built-in provider assumes you'll be storing to just one bucket. Still, you just need to override the appropriate sections of code in the provider to create your own implementation. Something like this:
public class CustomS3UploadStreamProvider : S3UploadStreamProvider
{
string _accessKeyId;
string _secretAccessKey;
public CustomS3UploadStreamProvider(UploadStreamProviderElement settings)
: base(settings)
{
accessKeyId = Settings.Parameters["accessKeyId"];
secretAccessKey = Settings.Parameters["secretAccessKey"];
}
public virtual string GetObjectName(UploadedFile file)
{
// TODO: return the correct object name (including path if desired)
}
public virtual string GetClientFor(UploadedFile file)
{
// TODO: specify the correct bucket name, based on biz logic;
string bucketName = "CHANGEME";
// TODO: maybe cache this?
return new S3BlobClient(accessKeyId, secretAccessKey, bucketName);
}
public override Stream GetWriteStream(UploadedFile file)
{
S3BlobInfo blobInfo = CreateBlobInfo(file);
file.ServerLocation = blobInfo.Name;
return GetClientFor(file).GetPutBlobStream(blobInfo);
}
public override void RemoveOutput(UploadedFile file)
{
GetClientFor(file).DeleteBlob(file.ServerLocation);
}
public override Stream GetReadStream(UploadedFile file)
{
return GetClientFor(file).GetBlob(file.ServerLocation);
}
}