can't replace file in amazon s3 bucket
when i am going to upload an image to amazon s3 bucket it shows error like below
An item with the same key has already been added.
i have uploaded an image file and i wanted replace that image when i need it. but it does not allow.
how can I fix it?
i am using C#
using (s3Client = Amazon.AWSClientFactory.CreateAmazonS3Client("key", "secret key", Amazon.RegionEndpoint.USWest2))
{
var stream2 = new System.IO.MemoryStream();
bitmap.Save(stream2, ImageFormat.Jpeg);
stream2.Position = 0;
PutObjectRequest request2 = new PutObjectRequest();
request2.InputStream = stream2;
request2.BucketName = "ezcimassets";
request2.CannedACL = S3CannedACL.PublicRead;
fileName = webpage + ".jpeg";
//fileName = Guid.NewGuid() + webpage + ".jpeg";)
request2.Key = "WebThumbnails/" + fileName;
Amazon.S3.Model.PutObjectResponse response = s3Client.PutObject(request2);
}
Thanks in advance
this line must be changed as
request2.CannedACL = S3CannedACL.PublicReadWrite
You can check if an object with that key already exists, and if so delete it:
public bool Exists(string fileKey, string bucketName)
{
try
{
response = _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;
}
}
public void Delete(string fileKey, string bucketName)
{
DeleteObjectRequest request = new DeleteObjectRequest();
request.BucketName = bucketName;
request.Key = fileKey;
client.DeleteObject(request);
}
Related
We are using S3 to store excel files. I first parse through the file to grab some data to save to the database before I upload it to the S3 bucket. Though I have yet to get this to happen on my local machine, when this is deployed, the tester sometimes sees the uploaded file being 0 KB even though it was parsed and data was saved to the database.It doesn't happen on my machine and only happens when deployed intermittently. Any ideas of how to resolve this?
[HttpPost("ingesttestmatrix")]
[ProducesResponseType(typeof(TestMatrixResponse), StatusCodes.Status200OK)]
public ActionResult<string> IngestTestMatrix([FromForm] Guid authenticateduserid, [FromForm] Guid testeventid, IFormFile filename)
{
TestMatrixResponse rsp = new TestMatrixResponse();
List<string> BadDataColumns = new List<string>();
Guid TestMatrixID = Guid.NewGuid();
//string newDictName = System.Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + #"\TempFiles" + Guid.NewGuid();
string newDictName = AppContext.BaseDirectory + #"\TempLLDBFiles" + Guid.NewGuid();
System.IO.Directory.CreateDirectory(newDictName);
string baseFileName = Request.Form.Files[0].FileName;
string newFileName = newDictName + #"\" + baseFileName;
try
{
//create file from stream and then open it for ingesting
var file = Request.Form.Files[0];
if (file.Length > 0)
{
using (FileStream fileStream = new FileStream(newFileName, FileMode.Create))
{
file.CopyTo(fileStream);
fileStream.Close();
}
}
//Do some cool db stuff
Model.Managers.AmazonFileManager.UploadFile(newFileName, testeventid.ToString()).Wait();
}
catch (Exception ex)
{
rsp.message = ex.Message.Replace("\"", "");
LoggingEvent lge = new LoggingEvent(LoggingEventTypeEnum.Error, "Ingest Test Matrix ", ex.Message, authenticateduserid.ToString());
LoggingEventController leController = new LoggingEventController();
leController.InsertLoggingEvent(authenticateduserid, lge, LoggingEventTypeEnum.Error);
rsp.success = false;
}};
public static async Task UploadFile(string filePath, string itemGuid)
{
try
{
var s3Client = new AmazonS3Client(Amazon.RegionEndpoint.USEast1);
var fileTransferUtility = new TransferUtility(s3Client);
string bucketName = "";
if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("AWSBucketName")))
bucketName = Environment.GetEnvironmentVariable("AWSBucketName");
else
bucketName = _iConfig.GetSection("AWSBucketName").Value;
PutObjectRequest putObjectRequest = new PutObjectRequest
{
BucketName = bucketName,
StorageClass = S3StorageClass.Standard,
Key = itemGuid + "/",
ContentBody = itemGuid
};
await s3Client.PutObjectAsync(putObjectRequest);
string fileKey = itemGuid + "/" + Path.GetFileName(filePath);
await fileTransferUtility.UploadAsync(filePath, bucketName, fileKey);
}
catch (AmazonS3Exception amazonS3Exception)
{
if (amazonS3Exception.ErrorCode != null &&
(amazonS3Exception.ErrorCode.Equals("InvalidAccessKeyId")
||
amazonS3Exception.ErrorCode.Equals("InvalidSecurity")))
{
throw new Exception("AWS Error: Check the provided AWS Credentials.");
}
else
{
throw new Exception("AWS Error: " + amazonS3Exception.Message);
}
}
}
I am wanting to create a WinForm application to upload selected files to digital ocean space. You can imagine it works similar to Cyberduck and written in C#. Thanks a lot
This worked for me to upload files to Digital ocean space
public static string UploadFile(HttpPostedFileBase file, string filepath)
{
try
{
string accessKey = "xxxxxxxxxxxxxxxxx";
string secretKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
AmazonS3Config config = new AmazonS3Config();
config.ServiceURL = "https://abc1.digitaloceanspaces.com";
AmazonS3Client s3Client = new AmazonS3Client(
accessKey,
secretKey,
config
);
// Create a client
AmazonS3Client client = new AmazonS3Client(RegionEndpoint.USEast1); //according to your prefered Region
try
{
var fileTransferUtility = new TransferUtility(s3Client);
var fileTransferUtilityRequest = new TransferUtilityUploadRequest
{
BucketName = bucketName + #"/" + filepath, // filepath is your folder name in digital ocean space leave empty if not any.
InputStream = file.InputStream,
StorageClass = S3StorageClass.StandardInfrequentAccess,
Key = file.FileName,
CannedACL = S3CannedACL.PublicRead
};
fileTransferUtility.Upload(fileTransferUtilityRequest);
}
catch (AmazonS3Exception e)
{
var a = e.Message;
}
}
catch (Exception ex) { }
return file.FileName;
}
So Im trying to upload a zip file to s3 for storage. But I keep getting 403 forbidden back.
My code works when i upload an image file but not when i upload a zip file
My code:
internal static void UploadFiletoS3fromZip(Byte[] fileByteArray, string fileName, string bucketName, string filepath)
{
try
{
CognitoAWSCredentials credentials = new CognitoAWSCredentials("###PVTCredentials###", Amazon.RegionEndpoint.EUWest1);
client = new AmazonS3Client(credentials, Amazon.RegionEndpoint.EUWest1);
using (MemoryStream fileToUpload = new MemoryStream(fileByteArray))
{
PutObjectRequest request = new PutObjectRequest()
{
BucketName = bucketName,
Key = fileName,
InputStream = fileToUpload,
ContentType = "application/zip"
};
request.Timeout = TimeSpan.FromSeconds(60);
PutObjectResponse response2 = client.PutObject(request);
}
}
catch (AmazonS3Exception s3Exception)
{
s3Exception.ToExceptionless().Submit();
}
catch (Exception ex)
{
ex.ToExceptionless().Submit();
}
}
Can anyone see what the problem here is? i get a 403 forbidden in the s3Exception. the credentials im using does have write permission and works perfectly when i use a base64 image and change the contentType to "image/jpeg"
OK SO I FOUND THE FIX....
instead of using
CognitoAWSCredentials credentials = new CognitoAWSCredentials("###PVTCredentials###", Amazon.RegionEndpoint.EUWest1);
client = new AmazonS3Client(credentials, Amazon.RegionEndpoint.EUWest1);
i replaced it with
var client = new AmazonS3Client(AwsAccessKeyId,AwsSecretAccessKey, Amazon.RegionEndpoint.EUWest1);
For if anyone else is having this issue, replace CognitoAWSCredentials with id and secret credentials
using (var client = new AmazonS3Client(LlaveAcceso, LlaveAccesoSecreta, RegionEndpoint.USEast2))
{
using (var newMemoryStream = new MemoryStream())
{
var putArchivo = new PutObjectRequest
{
BucketName = Buquet,
Key = file.FileName,
FilePath = ruta,
};
PutObjectResponse response = client.PutObjectAsync(putArchivo).Result;
MessageBox.Show("Archivo " + file.FileName + " Cargado Correctamente.", "AWS Loader", MessageBoxButtons.OK, MessageBoxIcon.Information);
label2.Text = "";
}
}
I have been trying to upload file to AWS S3 , below is the code that I am trying
private static void UploadToAWS(string localFilePath, string bucketName, string subDirectoryInBucket, string fileNameInS3)
{
string accessKey = ConfigurationManager.AppSettings["AMAZON_S3_ACCESSKEY"].ToString();
string secretKey = ConfigurationManager.AppSettings["AMAZON_S3_SECRETKEY"].ToString();
AmazonS3Config asConfig = new AmazonS3Config()
{
ServiceURL = "http://test.s3.amazonaws.com",
};
IAmazonS3 client = Amazon.AWSClientFactory.CreateAmazonS3Client(accessKey,secretKey,asConfig);
TransferUtility utility = new TransferUtility(client);
TransferUtilityUploadRequest request = new TransferUtilityUploadRequest();
if (subDirectoryInBucket == "" || subDirectoryInBucket == null)
{
request.BucketName = bucketName; //no subdirectory just bucket name
}
else
{ // subdirectory and bucket name
request.BucketName = bucketName + #"/" + subDirectoryInBucket;
}
request.Key = fileNameInS3; //file name up in S3
request.FilePath = localFilePath; //local file name
request.Headers.CacheControl = "public";
request.Headers.Expires = DateTime.Now.AddYears(3);
request.Headers.ContentEncoding = "gzip";
utility.Upload(request); //commensing the transfer
}
UploadToAWS(#"D:\core_gz.min.js", "test123", "test/build/", "core_gz.min.js");
When I execute this I get the following error
The request signature we calculated does not match the signature you
provided. Check your key and signing method.
Can any one help me here, what am I doing wrong here
I just wanted to post the answer if in case it might help some one else who has the same issue
private static void UploadToAWS(string localFilePath, string bucketName, string subDirectoryInBucket, string fileNameInS3)
{
string accessKey = ConfigurationManager.AppSettings["AMAZON_S3_ACCESSKEY"].ToString();
string secretKey = ConfigurationManager.AppSettings["AMAZON_S3_SECRETKEY"].ToString();
AmazonS3Config asConfig = new AmazonS3Config()
{
ServiceURL = "http://test.s3.amazonaws.com",
RegionEndpoint = Amazon.RegionEndpoint.APSoutheast1 // this line fixed the issue
};
IAmazonS3 client = Amazon.AWSClientFactory.CreateAmazonS3Client(accessKey,secretKey,asConfig);
TransferUtility utility = new TransferUtility(client);
TransferUtilityUploadRequest request = new TransferUtilityUploadRequest();
if (subDirectoryInBucket == "" || subDirectoryInBucket == null)
{
request.BucketName = bucketName; //no subdirectory just bucket name
}
else
{ // subdirectory and bucket name
request.BucketName = bucketName + #"/" + subDirectoryInBucket;
}
request.Key = fileNameInS3; //file name up in S3
request.FilePath = localFilePath; //local file name
request.Headers.CacheControl = "public";
request.Headers.Expires = DateTime.Now.AddYears(3);
request.Headers.ContentEncoding = "gzip";
utility.Upload(request); //commensing the transfer
}
Adding this line in the config fixed my issue
RegionEndpoint = Amazon.RegionEndpoint.APSoutheast1
Here is the working code in Python (using cURL):
#!/usr/bin/python
import pycurl
c = pycurl.Curl()
values = [
("key", "YOUR_API_KEY"),
("image", (c.FORM_FILE, "file.png"))]
# OR: ("image", "http://example.com/example.jpg"))]
# OR: ("image", "BASE64_ENCODED_STRING"))]
c.setopt(c.URL, "http://imgur.com/api/upload.xml")
c.setopt(c.HTTPPOST, values)
c.perform()
c.close()
Here's what I have in C#:
public void UploadImage()
{
//I think this line is doing something wrong.
//byte[] x = File.ReadAllBytes(#"C:\Users\Sergio\documents\visual studio 2010\Projects\WpfApplication1\WpfApplication1\Test\hotness2.jpg");
//If I do it like this, using a direct URL everything works fine.
string parameters = #"key=1b9189df79bf3f8dff2125c22834210903&image=http://static.reddit.com/reddit.com.header.png"; //Convert.ToBase64String(x);
WebRequest webRequest = WebRequest.Create(new Uri("http://imgur.com/api/upload"));
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.Method = "POST";
byte[] bytes = Encoding.ASCII.GetBytes(parameters);
Stream os = null;
try
{ // send the Post
webRequest.ContentLength = bytes.Length; //Count bytes to send
os = webRequest.GetRequestStream();
os.Write(bytes, 0, bytes.Length); //Send it
}
catch (WebException ex)
{
MessageBox.Show(ex.Message, "HttpPost: Request error");
}
finally
{
if (os != null)
{
os.Close();
}
}
try
{ // get the response
WebResponse webResponse = webRequest.GetResponse();
StreamReader sr = new StreamReader(webResponse.GetResponseStream());
MessageBox.Show(sr.ReadToEnd().Trim());
}
catch (WebException ex)
{
MessageBox.Show(ex.Message, "HttpPost: Response error");
}
}
Now, the things I noticed is that when I changed my API key in the parameters string to "239231" or whatever number, the response I got was: "Invalid API key." So I think something must be working right.
I placed my correct API key and now I get a different response: "Invalid image format. Try uploading a JPEG image."
The service I'm using accepts almost every image format, so I am 100% certain the error is in the way I'm sending the file. Can anyone shed some light?
EDIT!!!
It turns out when I upload a JPG image I get that gray box thing. If I upload a big jpg image I don't get anything. For example: http://i.imgur.com/gFsUY.jpg
When I upload PNG's, the image uploaded doesn't even show.
I'm certain the issue is the encoding. What can I do?
EDIT 2!!!
Now I'm 100% certain that the problem lies in the first line of the method. The File.ReadAllBytes() must be doing something wrong. If I upload a URL file, every works peachy: http://imgur.com/sVH61.png
I wonder what encoding I should use. :S
Try this:
string file = #"C:\Users\Sergio\documents\visual studio 2010\Projects\WpfApplication1\WpfApplication1\Test\Avatar.png";
string parameters = #"key=1df918979bf3f8dff2125c22834210903&image=" +
Convert.ToBase64String(File.ReadAllBytes(file));
You should correctly form a multipart POST request. See an example here: Upload files with HTTPWebrequest (multipart/form-data)
Read image posted by in API
public IHttpActionResult UpdatePhysicianImage(HttpRequestMessage request)
{
try
{
var form = HttpContext.Current.Request.Form;
var model = JsonConvert.DeserializeObject<UserPic>(form["json"].ToString());
bool istoken = _appdevice.GettokenID(model.DeviceId);
if (!istoken)
{
statuscode = 0;
message = ErrorMessage.TockenNotvalid;
goto invalidtoken;
}
HttpResponseMessage result = null;
var httpRequest = HttpContext.Current.Request;
if (httpRequest.Files.Count > 0)
{
var docfiles = new List<string>();
foreach (string file in httpRequest.Files)
{
var postedFile = httpRequest.Files[file];
// var filePath = uploadPath + postedFile.FileName;
// string fileUrl = Utility.AbsolutePath("~/Data/User/" + model.UserId.ToString());
string fileUrl = Utility.AbsolutePath("~/" + Utility.UserDataFolder(model.UserId, "Document"));
if (!Directory.Exists(fileUrl))
{
Directory.CreateDirectory(fileUrl);
Directory.CreateDirectory(fileUrl + "\\" + "Document");
Directory.CreateDirectory(fileUrl + "\\" + "License");
Directory.CreateDirectory(fileUrl + "\\" + "Profile");
}
string imageUrl = postedFile.FileName;
string naviPath = Utility.ProfileImagePath(model.UserId, imageUrl);
var path = Utility.AbsolutePath("~/" + naviPath);
postedFile.SaveAs(path);
docfiles.Add(path);
if (model.RoleId == 2)
{
var doctorEntity = _doctorProfile.GetNameVideoChat(model.UserId);
doctorEntity.ProfileImagePath = naviPath;
_doctorProfile.UpdateDoctorUpdProfile(doctorEntity);
}
else
{
var patientEntity = _PatientProfile.GetPatientByUserProfileId(model.UserId);
patientEntity.TumbImagePath = naviPath;
_PatientProfile.UpdatePatient(patientEntity);
}
}
result = Request.CreateResponse(HttpStatusCode.Created, docfiles);
}
else
{
result = Request.CreateResponse(HttpStatusCode.BadRequest);
}
}
catch (Exception e)
{
statuscode = 0;
message = "Error" + e.Message;
}
invalidtoken:
return Json(modeldata.GetData(statuscode, message));
}
Try changing :-
"application/x-www-form-urlencoded"
to
"multipart/form-data"
Try adding the content-type for the jpg into your multipart boundary.
See this uRL for examples (at the end)
http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2
Shot in the dark, but maybe create an instance of Image, save the file to a Stream and use that to read the bytes into an array then upload it.
As in:
Image i = System.Drawing.Image.FromFile("wut.jpg");
Stream stm = new Stream();
System.Drawing.Imaging.Encoder myEncoder = System.Drawing.Imaging.Encoder.Quality;
System.Drawing.Imaging.EncoderParameters paramz = new System.Drawing.Imaging.EncoderParameters(1);
myEncoderParameter = new EncoderParameter(myEncoder, 100L);
paramz.Param[0] = myEncoderParameter;
i.Save(stm, System.Drawing.Imaging.ImageFormat.Jpeg, paramz);
/* I'm lazy: code for reading Stream into byte[] here */