框架是.NET MVC+API,下面简称WebApi了。
最开始调用AWS S3,不报错,但是始终没有办法上传成功。
开始怀疑点:
1.框架
2.方法
3.异步
4.连接数据库
但是最后调查发现是因为配置文件中的Log导致
去除下面这一段配置就可以上传成功了。
1 <log4net> 2 <!--定义输出到文件中--> 3 <appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender"> 4 <file value="D:\Log\POC\" /> 5 <appendToFile value="true" /> 6 <rollingStyle value="Date" /> 7 <datePattern value="yyyy\\MM\\yyyyMMdd.'txt'" /> 8 <StaticLogFileName value="false"/> 9 <layout type="log4net.Layout.PatternLayout"> 10 <!--<conversionPattern value="(%file:%line) %-5level %logger [%property{NDC}] - %message%newline" />--> 11 <conversionPattern value="%-5level %message%newline" /> 12 </layout> 13 </appender> 14 15 16 <!--定义日志的输出媒介,下面定义日志以四种方式输出。也可以下面的按照一种类型或其他类型输出。--> 17 <root> 18 <!--文件形式记录日志--> 19 <appender-ref ref="LogFileAppender" /> 20 </root> 21 </log4net>
下面是调用部分,参考AWS的GitHub项目
先是建立连接,需要先配置好AccessKey,SecretKey
以及地点RegionEndpoint,中国北京是 Amazon.RegionEndpoint.CNNorth1
连接信息如下
1 #region 连接信息 2 string awsAccessKeyId = ConfigurationManager.AppSettings["awsAccessKeyId"].ToString(); 3 string awsSecretAccessKey = ConfigurationManager.AppSettings["awsSecretAccessKey"].ToString(); 4 string bucketName = ConfigurationManager.AppSettings["BucketName"].ToString(); 5 #endregion 6 7 #region 建立连接 8 //验证信息 9 AWSCredentials credentials = new BasicAWSCredentials(awsAccessKeyId, awsSecretAccessKey); 10 //配置 11 AmazonS3Config config = new AmazonS3Config() 12 { 13 RegionEndpoint = Amazon.RegionEndpoint.CNNorth1 14 }; 15 //建立连接 16 AmazonS3Client s3Client = new AmazonS3Client(credentials, config); 17 #endregion
上传部分,这里是本地文件上传
newFilePathName是本地文件路径,物理路径;
objRequest.Key是AWS S3存储tongu桶里面的名字,相当于主键,这个根据需要随意变更;
这里用的newFileName,是文件名。
1 #region 上传 2 //文件 3 PutObjectRequest objRequest = new PutObjectRequest(); 4 FileStream fileStream = new FileStream(newFilePathName, FileMode.Open, FileAccess.Read); 5 objRequest.InputStream = fileStream; 6 objRequest.BucketName = bucketName; 7 objRequest.Key = newFileName; 8 //上传文件 9 PutObjectResponse res = s3Client.PutObject(objRequest); 10 #endregion
获取url部分
AWS S3示例
1 // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 // SPDX-License-Identifier: MIT-0 3 // snippet-start:[s3.dotNET.GenPresignedURLTest] 4 using Amazon; 5 using Amazon.S3; 6 using Amazon.S3.Model; 7 using System; 8 9 namespace Amazon.DocSamples.S3 10 { 11 class GenPresignedURLTest 12 { 13 private const string bucketName = "*** bucket name ***"; 14 private const string objectKey = "*** object key ***"; 15 // Specify how long the presigned URL lasts, in hours 16 private const double timeoutDuration = 12; 17 // Specify your bucket region (an example region is shown). 18 private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USWest2; 19 private static IAmazonS3 s3Client; 20 21 public static void Main() 22 { 23 s3Client = new AmazonS3Client(bucketRegion); 24 string urlString = GeneratePreSignedURL(timeoutDuration); 25 } 26 static string GeneratePreSignedURL(double duration) 27 { 28 string urlString = ""; 29 try 30 { 31 GetPreSignedUrlRequest request1 = new GetPreSignedUrlRequest 32 { 33 BucketName = bucketName, 34 Key = objectKey, 35 Expires = DateTime.UtcNow.AddHours(duration) 36 }; 37 urlString = s3Client.GetPreSignedURL(request1); 38 } 39 catch (AmazonS3Exception e) 40 { 41 Console.WriteLine("Error encountered on server. Message:'{0}' when writing an object", e.Message); 42 } 43 catch (Exception e) 44 { 45 Console.WriteLine("Unknown encountered on server. Message:'{0}' when writing an object", e.Message); 46 } 47 return urlString; 48 } 49 } 50 } 51 // snippet-end:[s3.dotNET.GenPresignedURLTest]
项目应用的部分。
1 #region 获取 2 GetPreSignedUrlRequest urlRequest = new GetPreSignedUrlRequest 3 { 4 BucketName = bucketName, 5 Key = newFileName, 6 Expires = DateTime.UtcNow.AddHours(12) 7 }; 8 string urlString = s3Client.GetPreSignedURL(urlRequest); 9 #endregion
最后是引用。
第一行用来获取配置文件的,
后面Amazon开头的都是必不可少的调用S3必须的引用;
这几个引用可以通过Nuget来下载。
1 using System.Configuration; 2 using Amazon.S3; 3 using Amazon.S3.Model; 4 using Amazon.S3.Transfer; 5 using Amazon.Runtime;
最后的最后就是把他们装到一个类里去了
这里改动了一个地方,和上面不一样的地方,用了异步。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Configuration; 6 using Amazon; 7 using Amazon.S3; 8 using Amazon.S3.Model; 9 using Amazon.S3.Transfer; 10 using Amazon.Runtime; 11 using System.Threading.Tasks; 12 using System.IO; 13 14 namespace XXX 15 { 16 public class AmazonS3Upload 17 { 18 #region 连接信息 19 static string awsAccessKeyId = ConfigurationManager.AppSettings["awsAccessKeyId"].ToString(); 20 static string awsSecretAccessKey = ConfigurationManager.AppSettings["awsSecretAccessKey"].ToString(); 21 static string bucketName = ConfigurationManager.AppSettings["BucketName"].ToString(); 22 #endregion 23 24 #region 建立连接 25 //验证信息 26 static AWSCredentials credentials = new BasicAWSCredentials(awsAccessKeyId, awsSecretAccessKey); 27 //配置 28 static AmazonS3Config config = new AmazonS3Config() 29 { 30 RegionEndpoint = Amazon.RegionEndpoint.CNNorth1 31 }; 32 //建立连接 33 AmazonS3Client s3Client = new AmazonS3Client(credentials, config); 34 #endregion 35 36 /// <summary> 37 /// 上传文件 38 /// </summary> 39 /// <param name="newFilePathName"></param> 40 /// <param name="newFileName"></param> 41 public async Task UploadAnObject(string newFilePathName, string newFileName) 42 { 43 try 44 { 45 PutObjectRequest objRequest = new PutObjectRequest(); 46 FileStream fileStream = new FileStream(newFilePathName, FileMode.Open, FileAccess.Read); 47 objRequest.InputStream = fileStream; 48 objRequest.BucketName = bucketName; 49 objRequest.Key = newFileName; 50 //上传文件 51 PutObjectResponse res = await s3Client.PutObject(objRequest); 52 } 53 catch (AmazonS3Exception e) 54 { 55 Console.WriteLine( 56 "Error encountered ***. Message:'{0}' when writing an object" 57 , e.Message); 58 } 59 catch (Exception e) 60 { 61 Console.WriteLine( 62 "Unknown encountered on server. Message:'{0}' when writing an object" 63 , e.Message); 64 } 65 } 66 67 /// <summary> 68 /// 获取文件地址 69 /// </summary> 70 /// <param name="newFileName"></param> 71 /// <returns></returns> 72 public string GeneratePreSignedURL(string newFileName) 73 { 74 string urlString = ""; 75 try 76 { 77 GetPreSignedUrlRequest request1 = new GetPreSignedUrlRequest 78 { 79 BucketName = bucketName, 80 Key = newFileName, 81 Expires = DateTime.UtcNow.AddHours(12) 82 }; 83 urlString = s3Client.GetPreSignedURL(request1); 84 } 85 catch (AmazonS3Exception e) 86 { 87 Console.WriteLine("Error encountered on server. Message:'{0}' when writing an object", e.Message); 88 } 89 catch (Exception e) 90 { 91 Console.WriteLine("Unknown encountered on server. Message:'{0}' when writing an object", e.Message); 92 } 93 return urlString; 94 } 95 } 96 }