How to append multiple files into formdata using jquery - c#

I am using a input type file with multiple attribute. I want to save the files into a folder. But i am not sure how to append multiple files. Help will be greatly appreciated.
Script
$(document).on('click', '.btnSubmit', function () {
var data = new FormData();
var files = $('[type="file"]').get(0).files;
if (files.length > 0) {
_.each(files, function (program, idx) {
data.append("file", program);
});
}
_appFun._ajaxcall({
type: "POST",
url: '/application/test/saveFiles',
type: 'POST',
data: data,
cache: false,
contentType: false,
processData: false,
success: function (data) {
//show content
alert('Success!')
}
});
});
C#
[HttpPost]
public ActionResult saveFiles()
{
string directory = AppSettings.Application.uploadFolder;
HttpPostedFileBase file = Request.Files["file"];
if (file != null && file.ContentLength > 0)
{
var fileName = Path.GetFileNameWithoutExtension(file.FileName);
string extension = Path.GetExtension(file.FileName);
var randomId = uniqId();
file.SaveAs(Path.Combine(directory, fileName + randomId + extension));
}
return RedirectToAction("Index");
}

If you are trying to cycle through the same input area, you can do:
var data = new FormData();
var files = $('[type="file"]')[0].files;
if (files.length > 0) {
var count = 0;
$(files).each(function(i, value){
count++;
var variableName = "name" + count;
data.append(variableName, value[i].files[0]);
}
}

Related

File Upload Through JQuery AJAX In ASP.NET MVC

I have a requirement of sending invitations to candidates where a user selects the excel file, transfers it from ajax to controller and validates its size, type etc. Then user clicks on Send Invite button and sends the email invites(having excel file). Please find the below code for reference:
<button type="button" id="bulkuploadButton">Bulk Email Upload</button>
<input type="file" id="ExcelFile" name="ExcelFile" style="display:none" onchange="UploadFile();" onselect="UploadFile();" accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel" />
Jquery:
function UploadFile() {
if (ValidateExcelFile()) {
var excelFile = document.getElementById('ExcelFile');
formData = new FormData();
if (excelFile.files.length > 0) {
for (var i = 0; i < excelFile.files.length; i++) {
formData.append('file-' + i, excelFile.files[i]);
}
}
$.ajax({
url: url here,
type: "POST",
dataType: 'json',
processData: false,
contentType: false,
data: formData,
success: function (data) {
// Further Processing
},
error: function (err) {
//Error
}
});
}
}
Controller:
[HttpPost]
public JsonResult MyController(HttpPostedFileBase excelFile)
{
if (Request.Files.Count > 0)
{
foreach (string file in Request.Files)
{
excelFile = Request.Files[file];
}
var result = //Call Model here for validation checks and return error msges
TempData["ExcelFile"] = excelFile; //Store in TempData for further processing
return Json(result);
}
return null;
}
The validations are done successfully, now its time to send invite to candidates as:
<button onclick="SendInvite">Send Invitations</button>
Jquery:
function SendInvite() {
//Check validations for other inputs on the page
//Get the excel file same as above
var excelFile = document.getElementById('ExcelFile');
formData = new FormData();
if (excelFile.files.length > 0) {
for (var i = 0; i < excelFile.files.length; i++) {
formData.append('file-' + i, excelFile.files[i]);
}
}
$.ajax({
type: "POST",
url: url here,
data: JSON.stringify({
myModel: myModel,
excelFile: formData
}),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
},
error: function (data) {
}
});
}
Controller:
public JsonResult MyController2(MyModel myModel, HttpPostedFileBase excelFile)
{
//I tried the same method to get the file but it didn't help me
if (Request.Files.Count > 0) //Here Request.Files.Count = 0, it should be = 1 instead
{
foreach (string file in Request.Files)
{
excelFile = Request.Files[file];
}
}
//I then tied to use TempData but it does not have the excel data
excelFile = TempData["ExcelFile"] as HttpPostedFileBase;
//Further processing
I am getting this error while fetching data from TempData. ContentLength is 0 and also the data attribute is null
The data in TempData should be something like this (where ContentLength !=0
and data attribute has some value):
Can anyone help me get the excel data in controller MyController2.
Change the function SendInvite() as:
function SendInvite() {
//Check validations for other inputs on the page
//Get the excel file same as above
var excelFile = document.getElementById('ExcelFile');
formData = new FormData();
formData.append("data", JSON.stringify(myModel));
for (var i = 0; i < excelFile.files.length; i++) {
var file = ExcelFile.files[i];
formData.append("excelFile", file);
}
$.ajax({
type: "POST",
url: url here,
data: formData,
contentType: "application/json; charset=utf-8",
dataType: "json",
contentType: false,
processData: false,
success: function (data) {
},
error: function (data) {
}
});
}
and in controller
public JsonResult MyController2(string data, HttpPostedFileBase[] excelFile)
{
MyModel myModel = JsonConvert.DeserializeObject<MyModel>(data);
if (Request.Files.Count > 0)
{
//Do data processing here
}
//Further processing
Check this link How to Pass Image File and Form Data From Ajax to MVC Controller

Ajax Response Doesn't work from server side (iis)

I try to save a file (image) on C# MVC and JS with the following function js
function Add() {
var data = new FormData();
var files = $("#txtUploadFile").get(0).files;
var cod = document.getElementById('cod').value;
var mat = document.getElementById('mat').value;
var status = document.getElementById('status').value;
var plant = document.getElementById('plant').value;
if (files.length > 0) {
if (window.FormData !== undefined) {
var data = new FormData();
for (var x = 0; x < files.length; x++) {
data.append("file" + x, files[x]);
data.append("mat", mat);
data.append("status", status);
data.append("plant", plant);
data.append("code", cod);
}
$.ajax({
type: 'POST',
url: '/Pred/Admin/AddPred',
contentType: false,
processData: false,
data: data,
success: function (response) {
if(response.msg == 1)
{
refreshTable(response.data);
}
alert('Predio agregado.');
},
error: function (xhr, status, p3, p4) {
var err = "Error " + " " + status + " " + p3 + " " + p4;
if (xhr.responseText && xhr.responseText[0] == "{")
err = JSON.parse(xhr.responseText).Message;
}
});
}
}
}
and on the codebehind I used it
public ActionResult AddPred()
{
int isInsert=0;
string route = ConfigurationManager.AppSettings["MAPS_ROUTE"];
string[] status, plants, mats, codes;
int stat;
try
{
var requeststatus = Request.Params;
status = requeststatus.GetValues("status");
plants = requeststatus.GetValues("plant");
codes = requeststatus.GetValues("cod");
mats = requeststatus.GetValues("mat");
if (status[0] == "On")
stat= 1;
else
stat= 0;
string plant = plants[0];
string mat = mats[0];
string code = codes[0];
foreach (string file in Request.Files)
{
var fileContent = Request.Files[file];
if (fileContent != null && fileContent.ContentLength > 0)
{
var fileName = fileContent.FileName;
var path = Path.Combine(Server.MapPath(route), fileName);
path = Server.MapPath(route) + fileName;
var sqlpath = "." + route + "/" + fileName;
fileContent.SaveAs(path);
isInsert = ma.InsertPred(code, mat, stat, plant, sqlpath);
}
}
merge.preds = ma.GetPreds();
return Json(new { success = true, data = merge.preds, msg = isInsert }, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return Json("add failed");
}
}
But the server response ever is
POST myserver/Preds/Admin/AddPred 500 (Internal Server Error)
and I used console.log but I can't to get the error information, When used this code on local side, it's runs Okey, save the image and return model for refresh the front, but when put the aplication on the server, only return error, others funtions works (modal show, return model with json) but doesn't work save a image, I set permissions (write, load, modify) on the server folder,
someone give a idea for solves this problem, I don't know whats wrong
Try like this :
function getCities(id) {
$.ajax({
type: "POST",
url: "#Url.Action("Index", "Default")",
data: '{id: id }',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
//alert(response.responseData);
window.location = '/Default/YourView';//
},
error: function (response) {
alert("error!"); //
}
});
}
//In your controller
public JsonResult Index(string id)
{
merge.country= mp.Country();
merge.city= mp.City(id);
return Json("you can return an object or a string, what you want");
}

'Not found' error in upload file using jquery and handler(ashx)

UploadHandler.ashx.cs
public class UploadHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
try
{
string dirFullPath = HttpContext.Current.Server.MapPath("~/Uploader/");
string[] files;
int numFiles;
files = System.IO.Directory.GetFiles(dirFullPath);
numFiles = files.Length;
numFiles = numFiles + 1;
string str_image = "";
foreach (string s in context.Request.Files)
{
HttpPostedFile file = context.Request.Files[s];
string fileName = file.FileName;
string fileExtension = file.ContentType;
if (!string.IsNullOrEmpty(fileName))
{
fileExtension = Path.GetExtension(fileName);
str_image = "MyPHOTO_" + numFiles.ToString() + fileExtension;
string pathToSave_100 = HttpContext.Current.Server.MapPath("~/Uploader/") + str_image;
file.SaveAs(pathToSave_100);
}
}
// database record update logic here ()
context.Response.Write(str_image);
}
catch (Exception ac)
{
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
JsCode
/Image Upload code
function sendFile(file) {
var formData = new FormData();
formData.append('file', $('#f_UploadImage')[0].files[0]);
$.ajax({
url: 'UploadHandler.ashx',
type: 'POST',
data: formData,
cache: false,
processData: false,
contentType: false,
success: function(result) {
if (result != 'error') {
var my_path = "Uploader/" + result;
$("#myUploadedImg").attr("src", my_path);
}
},
error: function(err) {
alert(err.statusText);
}
});
}
function callImgUploader() {
var _URL = window.URL || window.webkitURL;
$("#f_UploadImage").on('change', function() {
var file, img;
if ((file = this.files[0])) {
img = new Image();
img.onload = function() {
sendFile(file);
};
img.onerror = function() {
alert("Not a valid file:" + file.type);
};
img.src = _URL.createObjectURL(file);
}
});
}
Note: My Aspx page is different folder and Image Folder and UploadHandler.ashx.cs is route folder its wrong?
after run ajax request every time its give Not-Found error how can its fixed.
Thanks.
You didn't mentioned which upload control you are using , i'm assuming it is a server side and you need to access it as follows
Change
$('#f_UploadImage')
to
$('#<%= f_UploadImage.ClientID %>')
As you said
My Aspx page is different folder and Image Folder and UploadHandler.ashx.cs
You have to change
url: 'UploadHandler.ashx',
to
url: '/UploadHandler.ashx',
Otherwise it will try to search UploadHandler.ashx in the same folder as of ajax page and give 404.
I think the problem is with the contentType try
contentType: 'multipart/form-data',
Thanks for all of your valuable feedback,
now my problem has been fixed,
problem in UploadHandler.ashx setting
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="UploadHandler.ashx.cs" Inherits="Customer.UploadHandler" %>
inherits value are not matching my UploadHandler.ashx.cs namespace that's the problem, now its fixed.
Thanks everyone.

ajax call (to send file) to call c# function not working(webmethod)

This form i want to send using ajax call with file, but it is not calling the c# function and not showing any error.
//form to submit
<form id="formfile" enctype="multipart/form-data">
<div class="modal-body">
<input type="file" id="fileupload1"/>
</div>
<div class="modal-footer">
<input type="submit" id="savefiles" class="buttonType" onclick="saveFile();return false" value="Save File" />
</div>
</form>
This ajax call is used to call c# code and also send file(.pdf)
//ajax call in .aspx file
function saveFile() {
debugger;
var file = $('input[type="file"]').val();
var exts = ['pdf', 'PDF'];
var formData = new FormData();
formData.append("imageFile", $('#fileupload1')[0].files[0]);
if (file) {
var extension = file.substring(file.lastIndexOf('.') + 1, file.length);
if ($.inArray(extension, exts) > -1)
{
//var formData = new FormData($('#form1')[0]);
var fileUpload = $('#fileupload1').get(0);
var files = fileUpload.files;
for (var i = 0; i < files.length; i++) {
formData.append(files[i].name, files[i]);
}
formData.append(fileUpload.name, fileUpload);
//alert('File Uploaded Successfully!');
}
else
{
alert('Invalid file, Only pdf files can be uploaded!!!');
}
}
//var str = "abc";
$.ajax({
url: "FileUploader.aspx/savepdfFiles",
type: "POST",
//cache: false,
contentType: false,
processData: false,
data: formData,
success: function (data) {
debugger;
},
error: function (data) {
debugger
}
});
}
It will come into success section also, but not calling following method.
//c# code
[webMethod]
public static void savepdfFiles()
{
//code
}
In ajax call it goes into success. but not calling savepdfFiles() method.
EDIT 24/08/2016
You can convert your blob data to base 64 and send it in JSON
var filesLength = 0;
function SaveFileToTemp() {
var file = $('input[type="file"]').val();
var exts = ['pdf', 'PDF'];
var pdfList = [];
// var pdfFile = { FileName: '', B64Data: '' };
if (file) {
var extension = file.substring(file.lastIndexOf('.') + 1, file.length);
if ($.inArray(extension, exts) > -1) {
var fileUpload = $('#fileupload1').get(0);
var files = fileUpload.files;
filesLength = files.length;
for (var i = 0; i < files.length; i++) {
var reader = new window.FileReader();
reader.myFileIndex = i;
reader.onloadend = function () {
base64data = reader.result;
pdfList.push({ FileName: files[this.myFileIndex].name, B64Data: base64data.substr(base64data.indexOf(',') + 1) });
console.log(base64data);
filesLength--;
if (filesLength === 0) {
$.ajax({
url: "/FileUploader.aspx/savepdfFiles",
type: "POST",
//cache: false,
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify({ listPdf: pdfList }),
success: function (data) {
//alert('File Uploaded Successfully!');
debugger;
},
error: function (data) {
debugger
}
});
}
}
reader.readAsDataURL(files[i]);
}
}
else {
alert('Invalid file, Only pdf files can be uploaded!!!');
}
}
}
and in C#
[WebMethod]
public static void savepdfFiles(List<PdfFile> listPdf)
{
//code
foreach (var item in listPdf)
{
byte[] data = Convert.FromBase64String(item.B64Data);
System.IO.File.WriteAllBytes(string.Format("d:\\temp\\{0}",item.FileName), data) ;
}
}
this is my clas PdfFile for info
public class PdfFile
{
public string FileName { get; set; }
public string B64Data { get; set; }
}
Maybe you have to add this to your web.config to allow big json serialization :
<system.web.extensions>
<scripting>
<webServices>
<jsonSerialization maxJsonLength="10240000"/>
</webServices>
</scripting>
</system.web.extensions>
You have to set the appropiate value for maxJsonLength
Previous answer
I think I had this problem before from what i remember there is mechanism that doesn't allow you to this.
Maybe I'm wrong but I share you a link.
You will have to handle this with an ashx.
here is a built-in validation layer of protection that ASP.NET
enforces for both GET and POST based ASP.NET AJAX web methods, which
is that regardless of the HTTP verb being used, ASP.NET always
requires that the HTTP Content-Type header is set to the value
application/json. It this content type header is not sent, ASP.NET
AJAX will reject the request on the server.
I know this problem and it's easy to solve just you have to use Generic Handler.
Using generic handler with your AJAX call you can send any file to asp.net C# function.
In Generic Handler you have to write following c# code.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
namespace UploadFile
{
/// <summary>
/// Summary description for UploadFileHandler
/// </summary>
public class UploadFileHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
//context.Response.ContentType = "text/plain";
//context.Response.Write("Hello World");
if (context.Request.Files.Count > 0)
{
HttpFileCollection files = context.Request.Files;
for (int i = 0; i < files.Count; i++)
{
HttpPostedFile file = files[i];
string fname;
if (HttpContext.Current.Request.Browser.Browser.ToUpper() == "IE" || HttpContext.Current.Request.Browser.Browser.ToUpper() == "INTERNETEXPLORER")
{
string[] testfiles = file.FileName.Split(new char[] { '\\' });
fname = testfiles[testfiles.Length - 1];
}
else
{
fname = file.FileName;
}
fname = Path.Combine(context.Server.MapPath("~/Uploads/"), fname);
file.SaveAs(fname);
}
}
context.Response.ContentType = "text/plain";
context.Response.Write("File Uploaded Successfully!");
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
Here is the example...
If you want Full Example Click here!

Uploading Document to App_Data

I've currently got some working code that will upload a document to the App_data file, however I need to be able to differentiate the files uploaded if they have the same name. I want to do this by modifying the file name like so: ID" "Filename
I've had a few attempts to include this in the object thats passed to the controller but I can't find it stored anywhere (I presume that it gets stripped out when being passed?).
Here is my current code:
var files = $('#txtUploadFile')[0].files;
if (files.length > 0) {
if (window.FormData !== undefined) {
var data = new FormData();
for (var x = 0; x < files.length; x++) {
data.append("file" + x, files[x]);
}
// data.uploadName = task.Id + " " + files[0].name;
// File.filename = Id + " " + file.filename;
$.ajax({
type: "POST",
url: '../Document/UploadFiles/',
contentType: false,
processData: false,
//data: {'id': (nextRef + 1), 'fileLocation': files[0].name }, // THIS DOESN'T WORK
data: data, // THIS WORKS WITHOUT ANY OTHER VARIABLES
dataType: "json",
success: function (result) {
//alert(result);
},
error: function (xhr, status, p3, p4) {
var err = "Error " + " " + status + " " + p3 + " " + p4;
if (xhr.responseText && xhr.responseText[0] == "{")
err = JSON.parse(xhr.responseText).Message;
alert(log(err));
}
});
} else {
alert("This browser doesn't support HTML5 file uploads!");
}
}
[HttpPost]
public JsonResult UploadFiles()//string id, string fileLocation)
{
try
{
foreach (string file in Request.Files)
{
var hpf = Request.Files[file] as HttpPostedFileBase;
if (hpf.ContentLength == 0)
continue;
var fileContent = Request.Files[file];
if (fileContent != null && fileContent.ContentLength > 0)
{
// get a stream
var stream = fileContent.InputStream;
// and optionally write the file to disk
var fileName = Path.GetFileName(file);
var path = Path.Combine(Server.MapPath("~/App_Data/"), Path.GetFileName(hpf.FileName));
// Save the file
hpf.SaveAs(path);
}
}
}
catch (Exception)
{
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return this.Json("Upload failed");
}
return this.Json("File uploaded successfully");
}
change from url: '../Document/UploadFiles/', to url: '#Url.Action("UploadFiles","YourController")
and in your controller
public class YourController:Controller{
[HttpPost]
publiction ActionResult UploadFiles(){
if (Request.Files != null && Request.Files.Count > 0)
{
string path=Server.MapPath("~/App_Data");
Request.Files[0].SaveAs(path + fileName);
return Json("File uploaded","text/json",JsonRequestBehavior.AllowGet);
}
return Json("No File","text/json",JsonRequestBehavior.AllowGet);
}
}
your html should be
<div><input type="file" name="UploadFile" id="fileupload" Class="fileupload" />
</div>
your ajax call should be
$.ajax({
type: "POST",
url: '/MyController/UploadFiles?id=' + myID,
contentType: false,
processData: false,
data: data,
success: function(result) {
console.log(result);
},
error: function (xhr, status, p3, p4){
});
//and your controller
[HttpPost]
public JsonResult UploadFiles(string id)
{
// whatever you want to that id
}
Happy coding...

Categories

Resources