【问题标题】:AWS Lambda function in .NET throwing error when creating new file for s3 bucket (Could not determine content length).NET 中的 AWS Lambda 函数在为 s3 存储桶创建新文件时抛出错误(无法确定内容长度)
【发布时间】:2018-11-03 23:45:40
【问题描述】:

我正在开发一个使用 .NET core 2 的 AWS lambda 函数。这是我第一次使用 .NET 开发 AWS lambda 函数。我现在要做的就是这么简单,读取现有文件并用新名称(新名称)保存文件。读取文件工作正常。但是当我使用 PutObjectRequest 保存文件时,它给了我一个错误。

这是我的处理函数代码

public async Task<string> FunctionHandler(S3Event evnt, ILambdaContext context)
      {
         var s3Event = evnt.Records?[0].S3;
         if(s3Event == null)
         {
            return null;
         }

         try
         {
            if(s3Event.Object.Key.ToLower().Contains("thumb"))
            {
               //Console.WriteLine("The image is already a thumb file");
               return "The file is aready a thumb image file";
            }

            string[] pathSegments = s3Event.Object.Key.Split('/');
            string eventCode = pathSegments[0];
            string userEmail = pathSegments[1];
            string filename = pathSegments[2];
            string extension = Path.GetExtension(filename); //.jpeg with "dot"
            string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filename);

            using(var objectResponse = await this.S3Client.GetObjectAsync(s3Event.Bucket.Name, s3Event.Object.Key))
            {
               using(Stream responseStream = objectResponse.ResponseStream)
               {
                  //This code is throwing error
                  await this.S3Client.PutObjectAsync(new Amazon.S3.Model.PutObjectRequest
                  {
                     BucketName = s3Event.Bucket.Name,
                     Key = fileNameWithoutExtension + ".thumb" + extension,
                     InputStream = responseStream
                  });
               }
            }

            return "Thumbnail version of the image has been created";

         }
         catch(Exception e)
         {
            context.Logger.LogLine($"Error getting object {s3Event.Object.Key} from bucket {s3Event.Bucket.Name}. Make sure they exist and your bucket is in the same region as this function.");
            context.Logger.LogLine(e.Message);
            context.Logger.LogLine(e.StackTrace);
            throw;
         }
      }

当我运行测试函数时,它给了我这个错误。

{
  "errorType": "AggregateException",
  "errorMessage": "One or more errors occurred. (Could not determine content length)",
  "stackTrace": [
    "at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)",
    "at lambda_method(Closure , Stream , Stream , LambdaContextInternal )"
  ],
  "cause": {
    "errorType": "AmazonS3Exception",
    "errorMessage": "Could not determine content length",
    "stackTrace": [
      "at Amazon.S3.Model.Internal.MarshallTransformations.PutObjectRequestMarshaller.GetStreamWithLength(Stream baseStream, Int64 hintLength)",
      "at Amazon.S3.Model.Internal.MarshallTransformations.PutObjectRequestMarshaller.Marshall(PutObjectRequest putObjectRequest)",
      "at Amazon.Runtime.Internal.Marshaller.PreInvoke(IExecutionContext executionContext)",
      "at Amazon.Runtime.Internal.Marshaller.InvokeAsync[T](IExecutionContext executionContext)",
      "at Amazon.Runtime.Internal.CallbackHandler.<InvokeAsync>d__9`1.MoveNext()",
      "--- End of stack trace from previous location where exception was thrown ---",
      "at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()",
      "at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)",
      "at Amazon.S3.Internal.AmazonS3ExceptionHandler.<InvokeAsync>d__1`1.MoveNext()",
      "--- End of stack trace from previous location where exception was thrown ---",
      "at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()",
      "at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)",
      "at Amazon.Runtime.Internal.ErrorCallbackHandler.<InvokeAsync>d__5`1.MoveNext()",
      "--- End of stack trace from previous location where exception was thrown ---",
      "at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()",
      "at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)",
      "at Amazon.Runtime.Internal.MetricsHandler.<InvokeAsync>d__1`1.MoveNext()",
      "--- End of stack trace from previous location where exception was thrown ---",
      "at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()",
      "at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)",
      "at AwsS3Lambda.Function.<FunctionHandler>d__10.MoveNext() in C:\\Users\\Acer\\Desktop\\MementoCSharp\\memento-dotnet\\AwsS3Lambda\\Function.cs:line 99"
    ]
  },
  "causes": [
    {
      "errorType": "AmazonS3Exception",
      "errorMessage": "Could not determine content length",
      "stackTrace": [
        "at Amazon.S3.Model.Internal.MarshallTransformations.PutObjectRequestMarshaller.GetStreamWithLength(Stream baseStream, Int64 hintLength)",
        "at Amazon.S3.Model.Internal.MarshallTransformations.PutObjectRequestMarshaller.Marshall(PutObjectRequest putObjectRequest)",
        "at Amazon.Runtime.Internal.Marshaller.PreInvoke(IExecutionContext executionContext)",
        "at Amazon.Runtime.Internal.Marshaller.InvokeAsync[T](IExecutionContext executionContext)",
        "at Amazon.Runtime.Internal.CallbackHandler.<InvokeAsync>d__9`1.MoveNext()",
        "--- End of stack trace from previous location where exception was thrown ---",
        "at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()",
        "at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)",
        "at Amazon.S3.Internal.AmazonS3ExceptionHandler.<InvokeAsync>d__1`1.MoveNext()",
        "--- End of stack trace from previous location where exception was thrown ---",
        "at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()",
        "at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)",
        "at Amazon.Runtime.Internal.ErrorCallbackHandler.<InvokeAsync>d__5`1.MoveNext()",
        "--- End of stack trace from previous location where exception was thrown ---",
        "at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()",
        "at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)",
        "at Amazon.Runtime.Internal.MetricsHandler.<InvokeAsync>d__1`1.MoveNext()",
        "--- End of stack trace from previous location where exception was thrown ---",
        "at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()",
        "at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)",
        "at AwsS3Lambda.Function.<FunctionHandler>d__10.MoveNext() in C:\\Users\\Acer\\Desktop\\MementoCSharp\\memento-dotnet\\AwsS3Lambda\\Function.cs:line 99"
      ]
    }
  ]
}

出了什么问题,我该如何解决?如何保存新文件?

【问题讨论】:

    标签: c# .net amazon-web-services amazon-s3 aws-lambda


    【解决方案1】:

    我会改变:

    await this.S3Client.PutObjectAsync(new Amazon.S3.Model.PutObjectRequest
    {
        BucketName = s3Event.Bucket.Name,
        Key = fileNameWithoutExtension + ".thumb" + extension,
        InputStream = responseStream
    });
    

    到:

    await this.S3Client.PutObjectAsync(new Amazon.S3.Model.PutObjectRequest
    {
        BucketName = s3Event.Bucket.Name,
        Key = fileNameWithoutExtension + ".thumb" + extension,
        InputStream = responseStream,
        Headers.ContentLength = s3event.object.size
    });
    

    这告诉 S3 您要存储的对象有多大。当您获得实际的缩略图代码时,Headers.ContentLength 将改为缩略图的长度。

    【讨论】:

    • PutRequestObject 类中没有 Headers.ContentLength 这样的属性。没有 Headers 属性。
    • 您可以像这样设置内容标题值:new PutObjectRequest { Headers = { ContentLength = responseStream.Length } };
    猜你喜欢
    • 1970-01-01
    • 2019-05-10
    • 2020-12-06
    • 2018-06-19
    • 1970-01-01
    • 2017-09-13
    • 1970-01-01
    • 1970-01-01
    • 2019-01-03
    相关资源
    最近更新 更多