I uploaded the image to Amazon S3 Successfully but when I view the image it shows nothing.
My View :
public JsonResult Upload(SocialJobMediaModel socialJobMediaModel)
{
var imagePathErrorMessage = new ImagePathErrorMessage();
if (Request.Files.Count > 0)
{
_log = GetProcessorLogger("CompanyXcodes", "CompanyXcodes", 1);
StageMediaFileProcessor stageMediaFileProcessor = new StageMediaFileProcessor(_log);
imagePathErrorMessage = stageMediaFileProcessor.UploadMediaFilesToS3(Request.Files[0].InputStream, Request.Files[0].FileName,"1234");
}
}
public void BulkUpload(Stream stream, string fileName, NameValueCollection metadata, ILogger log = null)
{
// Prepare request
if (string.IsNullOrEmpty(AwsRegion))
{
Client = new AmazonS3Client(_awsAccessKey, _awsSecretKey);
}
else
{
var regionEndPoint = RegionEndpoint.GetBySystemName(AwsRegion);
Client = new AmazonS3Client(regionEndPoint);
}
var tu = new TransferUtility(Client);
var request = new TransferUtilityUploadRequest
{
InputStream = stream,
Key = KeyPath + fileName,
BucketName = BucketName,
CannedACL = S3CannedACL.PublicRead,
};
if (metadata != null)
{
foreach (var metaDataKey in metadata.AllKeys)
{
request.Metadata.Add(metaDataKey, metadata[metaDataKey]);
}
}
// Set up progress logging (if logger provided)
if (log != null)
request.UploadProgressEvent += (sender, e) =>
{
if (e.PercentDone % 10 == 0)
log.LogInfo("Uploaded {0} of {1} bytes ({2} %)", e.TransferredBytes, e.TotalBytes, e.PercentDone);
};
// Upload (synchronous)
tu.Upload(request);
}
I am able to upload the image Successfully but when I view the image it shows nothing.can any one help me on this
I tried to upload filepath instead of inputstream but it throws the error
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'm trying to add a new function where user can upload images and videos similar to facebook in blazor server .NET 6, I created a new api and followed microsoft documentation of uploading files, Everything is working so far with uploading up to 4 files, but when I'm trying to upload more than 4 it doesn't send a request to the api at all. and after a while it shows these two exceptionsenter image description here enter image description here
Here's the code I'm having: `
private List<File> files = new();
private List<UploadInfo> uploadResults = new();
private int maxAllowedFiles = 10;
private bool shouldRender;
protected override bool ShouldRender() => shouldRender;
private async Task OnInputFileChange(InputFileChangeEventArgs e)
{
shouldRender = false;
long maxFileSize = (long)(4 * Math.Pow(10, 8));
var upload = false;
using var content = new MultipartFormDataContent();
foreach (var file in e.GetMultipleFiles(maxAllowedFiles))
{
if (uploadResults.SingleOrDefault(
f => f.FileName == file.Name) is null)
{
try
{
var fileContent =
new StreamContent(file.OpenReadStream(maxFileSize));
fileContent.Headers.ContentType =
new MediaTypeHeaderValue(file.ContentType);
files.Add(new() { Name = file.Name });
content.Add(
content: fileContent,
name: "\"files\"",
fileName: file.Name);
upload = true;
}
catch (Exception ex)
{
Logger.LogInformation(
"{FileName} not uploaded (Err: 6): {Message}",
file.Name, ex.Message);
uploadResults.Add(
new()
{
FileName = file.Name,
ErrorCode = 6,
Uploaded = false
});
}
}
}
if (upload)
{
var client = ClientFactory.CreateClient();
var response =
await client.PostAsync($"https://localhost:7134/api/Files/FileUpload", content);
if (response.IsSuccessStatusCode)
{
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true,
};
using var responseStream =
await response.Content.ReadAsStreamAsync();
var newUploadResults = await JsonSerializer
.DeserializeAsync<IList<MediaAPI.UploadInfo>>(responseStream, options);
if (newUploadResults is not null)
{
uploadResults = uploadResults.Concat(newUploadResults).ToList();
}
}
}
shouldRender = true;
}`
When I try to debug it, the debug point disappears when it sends the request:
await client.PostAsync($"https://localhost:7134/api/Files/FileUpload", content);
Anyone has experiansed this issue before?
Thanks in advance.
Net core application. I have one rest API which will send files to another API.
Below is the logic inside first API to send files to second API.
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", await _tokenService.GetToken());
MultipartFormDataContent multipartFormData = new MultipartFormDataContent();
string contentJson = JsonConvert.SerializeObject(request);
HttpContent data = new StringContent(contentJson, Encoding.UTF8, "application/json");
multipartFormData.Add(data, "data");
foreach (var file in fileList)
{
if (file.Length <= 0)
continue;
var fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');
multipartFormData.Add(new StreamContent(file.OpenReadStream())
{
Headers =
{
ContentLength = file.Length,
ContentType = new MediaTypeHeaderValue(file.ContentType)
}
}, "File", fileName);
}
try
{
var response = await client.PostAsync("https://localhost:44370/apisendfile", multipartFormData);
}
catch (Exception ex)
{
}
}
I have second API as below
public async Task<ActionResult> SendMail([FromBody] MultipartFormDataContent formDataContent)
{
}
When I debug in my first API I receive error
Unsupported Media Type
I am trying all the way to figure it out but could not succeed. Can someone help me to identify this issue. Any help would be appreciated. Thanks
Well, you could try following way,
Web API Controller:
[HttpPost]
public string UploadMultipartFile()
{
var file = HttpContext.Current.Request.Files.Count > 0 ?
HttpContext.Current.Request.Files[0] : null;
if (file != null && file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(
HttpContext.Current.Server.MapPath("~/MrPerfectMaltipartFolder"),
fileName
);
file.SaveAs(path);
}
return file != null ? "/MrPerfectMaltipartFolder/" + file.FileName : null;
}
Folder Location:
Tested on Post Man:
Open Folder Location:
File Uploaded:
For N Type of Multipart Data Upload:
[HttpPost]
public object UploadMultipartFileList()
{
var uploadedFilesName = new List<string>();
if (HttpContext.Current.Request.Files.Count > 0)
{
int count = 0;
foreach (var item in HttpContext.Current.Request.Files)
{
var getFile = HttpContext.Current.Request.Files[count];
if (getFile != null)
{
var fileName = Path.GetFileName(getFile.FileName);
var path = Path.Combine(
HttpContext.Current.Server.MapPath("~/MrPerfectMaltipartFolder"),
fileName
);
getFile.SaveAs(path);
}
count++;
string file = "/MrPerfectMaltipartFolder/" + getFile.FileName;
uploadedFilesName.Add(file);
}
}
return uploadedFilesName;
}
Output:
Example Both Data and File:
[HttpPost]
public object UploadMultipartFileList()
{
HttpRequest multipartRquest = HttpContext.Current.Request;
//General Data Part
string engineerName = multipartRquest.Form["EngineerName"];
string engineerEmail = multipartRquest.Form["EngineerEmail"];
//File Upload Part
var FilesName = new List<string>();
if (HttpContext.Current.Request.Files.Count > 0)
{
int count = 0;
foreach (var item in HttpContext.Current.Request.Files)
{
var getFile = HttpContext.Current.Request.Files[count];
if (getFile != null)
{
var fileName = Path.GetFileName(getFile.FileName);
var path = Path.Combine(
HttpContext.Current.Server.MapPath("~/MrPerfectMaltipartFolder"),
fileName
);
getFile.SaveAs(path);
}
count++;
string file = "/MrPerfectMaltipartFolder/" + getFile.FileName;
FilesName.Add(file);
}
}
return FilesName;
}
Request Format:
Output:
Hope it would resolve your problem. Feel free to share if you still encounter any issues.
Correct API style :
[HttpPost("logfiles")] // etc
public async Task<IActionResult> AddLogFile(IFormFile reportFile)
{
//UploadFile with any options with correct property Name = "ReportFile"
// all assigment will do framework itself in default impl
if (reportFile == null || reportFile.Length <= 0)
{
Submit client side style :
using (MultipartFormDataContent httpContent = new MultipartFormDataContent())
{
// read bytes from memstream etc
//...
httpContent.Add((HttpContent) bytes, "ReportFile", "test.log");
I am getting 400 error code with bad request while request to file upload API.
I built the back-end and front-end for file uploading in asp.net core and it works in localhost when I run it with IIS in my PC (using visual studio 2017).
Both of saving and updating API are working in my local but update API is not working if I deploy the code
front-end code like below:
public static async Task<HttpResponseMessage> UploadFile(string uploadUrl, string filePath, FFFileInfo fileInfo)
{
string fileName = fileInfo.Name + "." + fileInfo.Extension;
string contentType = MimeTypes.GetMimeType(filePath);
using (var hc = new HttpClient())
{
hc.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(TokenType, AccessToken);
hc.DefaultRequestHeaders.Accept.Clear();
hc.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
Stream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
StreamContent streamContent = CreateFileContent(fileStream, fileName, contentType);
// StreamContent streamContent = CreateFileContent(fileStream, "image.jpg", "image/jpeg"); // Multiple file upload
var requestContent = new MultipartFormDataContent("Upload Id" + DateTime.Now.ToString(CultureInfo.InvariantCulture));
requestContent.Add(streamContent, fileInfo.Name, fileName);
var progressContent = new ProgressableStreamContent(
requestContent,
4096,
(sent, total) =>
{
//Console.WriteLine("Uploading {0}/{1}", sent, total);
int percentage = (int) Math.Round((double)(100 * sent) / total);
Console.Write("\r{0}\t{1}%", fileInfo.Path, percentage);
if (sent == total)
{
Console.WriteLine();
}
});
var response = await hc.PostAsync(new Uri(uploadUrl), progressContent);
return response;
}
}
backend code like below:
[HttpPost]
[DisableFormValueModelBinding]
public async Task<IActionResult> UploadFiles([FromQuery] FFFileInfo fileinfo)
{
if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
{
return BadRequest($"Expected a multipart request, but got {Request.ContentType}");
}
authUser = User.ToAuthUser();
userId = authUser.UserId();
customerId = authUser.CustomerId();
Server.Model.File new_file = new Server.Model.File();
var boundary = MultipartRequestHelper.GetBoundary(MediaTypeHeaderValue.Parse(Request.ContentType), _defaultFormOptions.MultipartBoundaryLengthLimit);
var reader = new MultipartReader(boundary, HttpContext.Request.Body);
var section = await reader.ReadNextSectionAsync();
MemoryStream writeStream = new MemoryStream();
byte[] content = null;
while (section != null)
{
ContentDispositionHeaderValue contentDisposition;
var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out contentDisposition);
int chunkSize = 1024;
byte[] byte_file = new byte[chunkSize];
int bytesRead = 0;
new_file.File_Content = byte_file;
if (hasContentDispositionHeader)
{
if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
{
//await section.Body.CopyToAsync(targetStream);
using (var byte_reader = new BinaryReader(section.Body))
{
do
{
bytesRead = byte_reader.Read(byte_file, 0, byte_file.Length);
if(bytesRead <= 0)
{
content = writeStream.ToArray();
}
writeStream.Write(byte_file, 0, bytesRead);
} while (bytesRead > 0);
content = writeStream.ToArray();
}
}
}
// Drains any remaining section body that has not been consumed and
// reads the headers for the next section.
section = await reader.ReadNextSectionAsync();
}
try
{
new_file = new Server.Model.File
{
File_Name = fileinfo.Name,
File_Path = fileinfo.Path,
File_Ext = fileinfo.Extension,
Check_Sum = fileinfo.Checksum,
ToolSerialNumber = fileinfo.ToolSerialNumber,
FileSize = fileinfo.Length,
File_Content = content,
UserId = userId,
CustomerId = customerId
};
}
catch (Exception ex)
{
return BadRequest(ex);
}
try
{
if (!fileService.isExist(new_file.File_Path, userId))
{
fileService.SaveFile(new_file);
}
else
{
Server.Model.File existing = fileService.GetFileByPath(new_file.File_Path, userId);
fileService.UpdateFile(existing, new_file);
}
//set file content to null to response with small data
new_file.File_Content = null;
return Ok(new_file);
}
catch (Exception ex)
{
logger.LogError("DB action error {0}", ex.ToString());
return BadRequest(ex);
}
}
As you can see the above code, saving and updating are using same code but only updating is not working when it is deployed.
It is very strange for me.
I found the solution.
This code was deployed by my client I couldn't check the database that he deployed.
Based on researching and testing, I got an idea that might be related with permission issue.
So, we check it for db.
At the end, we found that current user has insert, delete, select permission but have not update permission.
After granting the update permission, it is working perfectly
I am trying to look at the fields of a Multipart upload and based on the contents of the string fields decide if I want to extract the attached files or not.
So it seemed reasonable to create a Custom MultiPartFormDataStreamprovider and check in there but when I try to copy the data via CopyToAsync pointing at a filestream I get no data. It seems the stream has already been read. What am I doing wrong?
internal class CustomMultipartFormDataStreamProvider : MultipartFormDataStreamProvider
{
isValidFields _validateFields;
internal CustomMultipartFormDataStreamProvider(string path, isValidFields validateFields) : base(path) { _validateFields = validateFields; }
private readonly Collection _isFormData = new Collection();
// private readonly NameValueCollection _formData = new NameValueCollection(StringComparer.OrdinalIgnoreCase);
//public NameValueCollection FormData
//{
//get { return _formData; }
//}
public override async Task ExecutePostProcessingAsync()
{
for (var index = 0; index < Contents.Count; index++)
{
if (IsStream(index))
continue;
var formContent = Contents[index];
var contentDisposition = formContent.Headers.ContentDisposition;
var formFieldName = UnquoteToken(contentDisposition.Name) ?? string.Empty;
var formFieldValue = await formContent.ReadAsStringAsync();
FormData.Add(formFieldName, formFieldValue);
}
if (_validateFields != null)
{
if (_validateFields(FormData) == false)
{
throw new Exception("Invalid data");
}
}
for (var index = 0; index < Contents.Count; index++)
{
if (!IsStream(index))
continue;
var formContent = Contents[index];
var contentDisposition = formContent.Headers.ContentDisposition;
var formFieldName = UnquoteToken(contentDisposition.Name) ?? string.Empty;
FileStream fileStream = null;
string pathname = Path.Combine(base.RootPath, Path.GetFileName(GetLocalFileName(formContent.Headers)));
using (fileStream = new FileStream(pathname, FileMode.Create, FileAccess.Write, FileShare.None))
{
try
{
await formContent.CopyToAsync(fileStream).ContinueWith((copyTask) =>
{
fileStream.Close();
});
}
catch (Exception ex)
{
throw;
}
}
}
}
private static string UnquoteToken(string token)
{
if (string.IsNullOrWhiteSpace(token))
return token;
if (token.StartsWith("\"", StringComparison.Ordinal) && token.EndsWith("\"", StringComparison.Ordinal) && token.Length > 1)
return token.Substring(1, token.Length - 2);
return token;
}
public bool IsStream(int idx)
{
return !_isFormData[idx];
}
public override Stream GetStream(HttpContent parent, HttpContentHeaders headers)
{
if (parent == null) throw new ArgumentNullException("parent");
if (headers == null) throw new ArgumentNullException("headers");
var contentDisposition = headers.ContentDisposition;
if (contentDisposition != null)
{
_isFormData.Add(String.IsNullOrEmpty(contentDisposition.FileName));
Stream result = base.GetStream(parent, headers);
return result;
}
throw new InvalidOperationException("Did not find required 'Content-Disposition' header field in MIME multipart body part.");
}
public override string GetLocalFileName(HttpContentHeaders headers)
{
return headers.ContentDisposition.FileName.Replace("\"", string.Empty);
}
}
this is called by
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
string guid = Guid.NewGuid().ToString();
string fileSaveLocation = HttpContext.Current.Server.MapPath("~/App_Data");
if (subDir.Length > 0)
Path.Combine(fileSaveLocation, subDir);
fileSaveLocation = Path.Combine(fileSaveLocation, guid);
Directory.CreateDirectory(fileSaveLocation);
CustomMultipartFormDataStreamProvider provider = new CustomMultipartFormDataStreamProvider(fileSaveLocation, validateFields);
try
{
// Read all contents of multipart message into CustomMultipartFormDataStreamProvider and allow validation of fields
await Request.Content.ReadAsMultipartAsync(provider);
okay by using the MultipartMemoryStreamProvider the xtraction to file can be held off and the functionality of MultiPartFormDataStreamprovider replicated, but with more control.