Kevin Salicos
Kevin Salicos

Reputation: 25

How to send HttpPostedFileBase to S3 via AWS SDK

I'm having some trouble getting uploaded files to save to S3. My first attempt was:

Result SaveFile(System.Web.HttpPostedFileBase file, string path)
{
    //Keys are in web.config
    var t = new Amazon.S3.Transfer.TransferUtility(Amazon.RegionEndpoint.USWest2);
    try
    {
        t.Upload(new Amazon.S3.Transfer.TransferUtilityUploadRequest
        {
            BucketName = Bucket,
            InputStream = file.InputStream,
            Key = path
        });
    }
    catch (Exception ex)
    {
        return Result.FailResult(ex.Message);
    }
    return Result.SuccessResult();
}

This throws an exception with the message: "The request signature we calculated does not match the signature you provided. Check your key and signing method." I also tried copying file.InputStream to a MemoryStream, then uploading that, with the same error.
If I set the InputStream to:

new FileStream(@"c:\folder\file.txt", FileMode.Open)

then the file uploads fine. Do I really need to save the file to disk before uploading it?

Upvotes: 1

Views: 2244

Answers (2)

danteMesquita
danteMesquita

Reputation: 107

Following the comment of shenku, for newer versions of SDK.

public bool Upload(string filePath, Stream inputStream, double contentLength, string contentType)
{
  try
  {
      var request = new PutObjectRequest();
      string _bucketName = "";

      request.BucketName = _bucketName;
      request.CannedACL = S3CannedACL.PublicRead;
      request.InputStream = inputStream;
      request.Key = filePath;
      request.Headers.ContentType = contentType;

      PutObjectResponse response = _amazonS3Client.PutObject(request);

      return true;

  }catch(Exception ex)
  {
      return false;
  }
}

Upvotes: 1

shenku
shenku

Reputation: 12438

This is my working version first the upload method:

   public bool Upload(string filePath, Stream inputStream, double contentLength, string contentType)
    {

        try
        {
            var request = new PutObjectRequest();

            request.WithBucketName(_bucketName)
                .WithCannedACL(S3CannedACL.PublicRead)
                .WithKey(filePath).InputStream = inputStream;

            request.AddHeaders(AmazonS3Util.CreateHeaderEntry("ContentType", contentType));

            _amazonS3Client.PutObject(request);

        }
        catch (Exception exception)
        {
          // log or throw;
          return false;
        }

        return true;
    }

I just get the stream from HttpPostedFileBase.InputStream

(Note, this is on an older version of the Api, the WithBucketName syntax is no longer supported, but just set the properties directly)

Upvotes: 3

Related Questions