I have an ajax function where I post multiple files in an array. How can store these files? I tried the following code in controller but only the first file is being stored.
foreach ($request->photos as $imagefile) {
$imageName = $imagefile->getClientOriginalName();
$imagePath = public_path('folder-path/');
$imagefile->move($imagePath,$imageName);
}
also this is how my array looks like
array from ajax
as #innovin requested.
Blade File
<input name="files[]" type="file" class="form-control" accept="image/png, image/jpeg" multiple id="files">
Update
function otherUpload(){
var outputdata = [];
var fileSelect = document.getElementById('files');
var files = fileSelect.files;
var formData = new FormData();
// Loop through each of the selected files.
for (var i = 0; i < files.length; i++) {
var file = files[i];
// Check the file type.
if (!file.type.match('image.*')) {
continue;
}
// Add the file to the request.
formData.append('photos[]', file, file.name);
}
$.ajax({
type: "POST",
url: 'post-url',
contentType: false,
processData: false,
dataType:'json',
data: formData,
success:function(data) {
if(data.code == 1){
console.log(data);
fetchOtherImages();
}
}
});
}
</script>```
you should loop through $request->file('photos') instead of $request->photos
if($request->hasfile('photos'))
{
foreach($request->file('photos') as $photo)
{
$name = $photo->getClientOriginalName();
$file->move(public_path('folder-path'), $name);
// to store file in Storage folder:
//$file->storeAs('files', $name);
}
}
note that he function GetClientOriginalName() is used to retrieve the file's original name at the time of upload in laravel, and that'll only be possible if the data is sent as array and not as a string. Hence, you must add enctype="multipart/form-data" whenever you are creating a form with input fields for files or images.
Related
I have this project in ASP.Net MVC that needs to upload multiple files. I can do it using FormData.Append. However, it is also needed to have a file description for each file.
Below is the page sample.
In each description, there should be a file to be uploaded in a database table with these 3 important columns.
FileName - nvarchar(max)
FileData - varbinary(max)
FileDescription - nvarchar(max)
In my View, I also have public HttpPostedFileBase FileUpload { get; set; } .
I am able to save the file but I cannot save the description for each file.
In my cshtml, I load the description through an html table (each description has an ID).
(some select query here, chklist = "Select DescriptionID, FileDescription FROM FileDescriptionMasterTable"). . .
foreach (var det in chklist)
{
<table id="#DescriptionID" class="table table-sm">
<tr>
<td class="w-75" id="chklst-#det.CheckList_Code">
#FileDescription
</td>
<td class="w-25">
<input type="file" accept=".pdf" id="myfile-#DescriptionID" multiple onchange="getFile(this)" />
</td>
</tr>
</table>
}
Then, this is the javascript for appending FormData.
var formdata = new FormData(); //FormData object
function getFile(e) {
var fileInput = document.getElementById(e.id);
//Iterating through each files selected in fileInput
for (i = 0; i < fileInput.files.length; i++) {
var sfilename = fileInput.files[i].name;
formdata.append(sfilename , fileInput.files[i]);
}
}
Here is my javascript to pass formdata to my controller:
$("#btnupload").click(function () {
$.ajax({
url: '/Attach/SaveFile',
type: "POST",
contentType: false, // Not to set any content header
processData: false, // Not to process data
data: formdata,
async: false,
accept: 'application/json',
success: function (r) {
alert("RFP has been saved successfully.");
window.location = "/Home";
},
error: function (xhr, status, error) {
alert(xhr.responseText);
}
});
});
Here is my Controller to save file:
public JsonResult SaveFile()
{
using myModeldb = new myModel())
{
HttpFileCollectionBase files = Request.Files;
for (int i = 0; i < files.Count; i++)
{
var description= Request["sfilename"]; //This part has no value since I cannot append the description for each file
HttpPostedFileBase file = files[i];
string fname;
// Checking for Internet Explorer
if (Request.Browser.Browser.ToUpper() == "IE" || Request.Browser.Browser.ToUpper() == "INTERNETEXPLORER")
{
string[] testfiles = file.FileName.Split(new char[] { '\\' });
fname = testfiles[testfiles.Length - 1];
}
else
{
fname = file.FileName;
}
Stream str = file.InputStream;
BinaryReader Br = new BinaryReader(str);
Byte[] FileDet = Br.ReadBytes((int)str.Length);
FileUpload pdf = new FileUpload
{
FileName = file.FileName,
FileDescription = description,
FileData = FileDet
};
db.FileUploads.Add(pdf);
db.SaveChanges();
}
string message = "SUCCESS"; //FileName and FileData (varbinary) is saved
return Json(new { Message = message, JsonRequestBehavior.AllowGet });
}
}
How am I able to fetch the description of each chosen file so I can also save it to the database?
Thanks in advance.
I have a problem in appending file object with form data,after appending file object to form data,form data is empty object.Please suggest
scope.uploadDigitalSignature = function (form) {
if (scope.digitalFiles.length) {
scope.docDetails.aliasName = scope.docDetails.aliasName;
scope.docDetails.digipassword = scope.docDetails.digipassword;
scope.docDetails.certificate = scope.docDetails.certificate;
var file = scope.digitalFiles[0];
var formData = new FormData(this);
formData.append('file', file);
// FileUpload.upload(scope.digitalFiles,docId,function(success,blobData){
var config = {
headers: {
'Content-Type': 'multipart/form-data',
}
};
var blobData = {
"file" : scope.docDetails.certificate
};
AdminService.uploadDigitalSignature(function(){
toastr.success('Signature uploaded successfully');
},docId,scope.docDetails.aliasName,scope.docDetails.digipassword ,blobData,config);
//}
//);
}
};
A FormData Object is an exotic object whose contents is not directly available to JavaScript.
To retrieve the contents of a FormData object, use its .entries() method:
var contents = Array.from(formData.entries());
console.log(contents);
For more information, see MDN Web API Reference - FormData.entries()
I have a function that will determine if the gif is animated or non-animated. Everything is working fine, until i upload those gif to the server, and load it, the blob url is a empty string. How can i generate a blob url for this?
Due to the blob url being empty string, i get parameter 1 is not of type 'blob'
The function below determines if the gif is animated or not.
$scope.isNotAnimatedGIF = function(file) {
var reader = new FileReader();
return new Promise(function(resolve, reject) {
reader.onload = function (e) {
var gifInfo = gify.getInfo(reader.result);
if (gifInfo.images.length <= 1) {
file.animatedGIF = false;
resolve(true);
} else {
file.animatedGIF = true;
resolve(false);
}
}
reader.readAsArrayBuffer(file);
});
}
I am using Angular 1.4.10
Thank you !
You can use URL.createObjectURL() to create Blob url.
The URL.createObjectURL() static method creates a DOMString containing a URL representing the object given in the parameter. The URL lifetime is tied to the document in the window on which it was created. The new object URL represents the specified File object or Blob object.
DEMO
function createbloburl(file, type) {
var blob = new Blob([file], {
type: type || 'application/*'
});
file = window.URL.createObjectURL(blob);
return file;
}
document.querySelector('#file').addEventListener('change', function(e) {
var file = e.currentTarget.files[0];
if (file) {
file = createbloburl(file, file.type);
document.querySelector('iframe').src = file;
//console.log(file)
}
})
<input id="file" type="file">
<iframe src=""></iframe>
try this reader.readAsDataURL(Blob|File).
you can find more from here
Background:
I have an AngularJS front end uploading files to an ASP.NET backend. I have a custom MultipartStreamProvider that is persisting the data to Azure. The only problem I have now is that the existing angular code is not submitting the file size, only the filename in the content disposition header
MyMultipartFormDataStreamProvider : MultipartStreamProvider
{
// ...
public override Stream GetStream(HttpContent parent, HttpContentHeaders headers)
{
// For form data, Content-Disposition header is a requirement
ContentDispositionHeaderValue contentDisposition = headers.ContentDisposition;
if (contentDisposition != null)
{
// create default filename if its missing
contentDisposition.FileName = (String.IsNullOrEmpty(contentDisposition.FileName) ? $"{Guid.NewGuid()}.data" : contentDisposition.FileName);
var size = contentDisposition.Size; // This is null right now!
}
}
}
and here is the angular code
$scope.$watch('files', function (files) {
$scope.formUpload = false;
console.log(files);
if (files != null) {
for (var i = 0; i < files.length; i++) {
$scope.errorMsg = null;
(function (file) {
file.size = 25;
upload(file);
})(files[i]);
}
}
});
function upload(file) {
file.upload = Upload.upload({
url: window.location.origin + "/api/mydocs/uploadfile?clientFolder=" + $scope.attachmentFolder + "&clientId=" + $scope.clientId + "&userId=" + $scope.currentUser.UserId,
method: 'POST',
headers: {},
fields: {},
file: file
});
Question:
How can I make Angular include the file size in the Content Disposition Header?
Thanks!
I have used this file upload directive in the past with great success. It will return the file size on the client side once your file is processed by the directive.
ngFileUpload
I'm editing this post to show my latest attempt per suggestions below.
I have been searching the forums trying to find a solution. I have an ASP.NET MVC Application in which I use Angular. I am trying to use danialfarid/ng-file-upload to allow users to upload PDFs which then get saved to the database as binary data (not my idea, but I have to do it that way).
I have the following (taken from the examples) in my HTML:
File:<input type="file" ngf-select ng-model="picFile" name="file" accept="image/*" ngf-max-size="2MB" required ngf-model-invalid="errorFile"><br />
<img ngf-thumbnail="picFile" class="thumb"> <button ng-click="picFile = null" ng-show="picFile">Remove</button><br />
<button type="button" class="btn btn-primary" ng-click="uploadPic(picFile)">Upload</button>
And this in my Angular controller:
$scope.uploadPic = function (files) {
file.upload = Upload.upload({
url: '/SSQV4/SSQV5/Document/UploadEMRDocument',
data: {file: files}
})
}
My MVC Controller:
namespace SSQV5.Controllers
{
public class DocumentController : ApiController
{
public async Task<IHttpActionResult> UploadEMRDocument()
{
try
{
var provider = new MultipartMemoryStreamProvider();
await Request.Content.ReadAsMultipartAsync(provider);
var f = provider.Contents.First(); // assumes that the file is the only data
if (f != null)
{
var filename = f.Headers.ContentDisposition.FileName.Trim('\"');
filename = Path.GetFileName(filename);
var buffer = await f.ReadAsByteArrayAsync();
//buffer now contains the file content,
//and filename has the original filename that was uploaded
//do some processing with it (e.g. save to database)
}
else
{
return BadRequest("Attachment failed to upload");
}
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
return Ok();
}
}
}
This code never hits the MVC Controller at all. I'm obviously missing something, but I haven't the slightest clue as to what it could be. Any assistance is greatly appreciated!
You need to extract the file content out of the form data.
Below is how I do this (using ng-file-upload in the same manner as you from the front end) to upload attachments in my application.
public async Task<IHttpActionResult> UploadAttachment()
{
// Check if the request contains multipart/form-data.
try
{
var provider = new MultipartMemoryStreamProvider();
await Request.Content.ReadAsMultipartAsync(provider);
var f = provider.Contents.First(); // assumes that the file is the only data
if (f != null)
{
var filename = f.Headers.ContentDisposition.FileName.Trim('\"');
filename = Path.GetFileName(filename);
var buffer = await f.ReadAsByteArrayAsync();
//buffer now contains the file content,
//and filename has the original filename that was uploaded
//do some processing with it (e.g. save to database)
}
else
{
return BadRequest("Attachment failed to upload");
}
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
return Ok();
}
When you configure the upload, you specify the URL where the file will be posted to:
file.upload = Upload.upload({
url: 'myMVC/MyMethod',
data: {file: file}
})