Where does formData ever get used in the controller? - javascript

I've seen many examples of uploading files asynchronously using AJAX and ASP.NET MVC, and I can't figure out if/how the Javascript FormData object ever gets used in the controller. The examples I see look like
var formData = new FormData();
formData.append("something", e.target.files[0]););
$.ajax({
type: "POST",
url: '#Url.Action("upload","someController")',
data: formData,
[HttpPost]
public async Task<JsonResult> upload ( )
{
try
{
foreach (string file in Request.Files)
{
var fileContent = Request.Files[file];
if (fileContent != null && fileContent.ContentLength > 0)
{
but I'm confused about how to formData is ever used in the controller. If it is used, how does it get inside a controller that has a blank parameter list?

Related

How to add custom properties to file form javascript / jquery

I'm aiming to send fileform with images and additional information like height and width. I can't figure out how to add some custom props to file form object.
$("#saveImg").on('click', function () {
var formData = new FormData(),
allFiles = [];
$('input[name=fileUpload]').each(function (index) {
if (inputFileValidation(this)) {
(function (files) {
if (files.length != 0) { allFiles.push(files[0]); }
})(this.files)
}
});
for (var i = 0; i != allFiles.length; i++) {
var img = new Image()
img.src = window.URL.createObjectURL(allFiles[i]);
$(img).on('load', function () {
formData.append("files_h", img.naturalHeight);
formData.append("files_w", img.naturalWidth);
formData.append("files", allFiles[i]);
window.URL.revokeObjectURL(allFiles[i]);
});
}
$.ajax({
url: '#Url.Action("Upload", "Image")',
data: formData,
processData: false,
contentType: false,
type: "POST",
success: function () {}
errors: function () {}
});
});
[HttpPost]
public async Task<IActionResult> Upload (IList<IFormFile> files)
{
//do something ;
}
I also tried:
[HttpPost]
public async Task<IActionResult> Upload (IList<IFormFile> files, IList<IFormFile> files_h, IList<IFormFile> files_w)
{
//do something ;
}
Maybe you have another idea how to send image with additional data? I tried to convert file form and additional info to JSON by that didn't work.
Edit
Thank you all for your suggestion, they are really important to me because I will definitely use them in the future.
However, in this project I have already given up using the file reader due to its asynchrony and having fun with promise. The aim is simple and less javascript and more c#
I apologize for misleading you in the title javascript andjquery - and I mark the answer related to c #. I did this because this answer is related to my next task because the CoreCompat.System.Drawing library is undoubtedly still useful for editing photos in the future.
Thanks!!
If you want to get the Width and Height properties while uploading images in ASP.NET Core. I suggest you to install this package: CoreCompat.System.Drawing
Install-Package CoreCompat.System.Drawing -Version 1.0.0-beta006
In the server, after saving your files to the specific path. You could use System.Drawing.Image class to get the Width and Height properties:
using (var image = System.Drawing.Image.FromFile(filePath))
{
int width = image.Width;
int height = image.Height;
}
You don't have to add files_h and files_w properties to your client model before sending to server.
And then, by using this way, I've edited your js code to:
$("#saveImg").on('click', function () {
var formData = new FormData();
for (var input of Array.from($('input[name=fileUpload]')))
{
if (inputFileValidation(input) && input.files.length) {
formData.append('files', input.files[0]);
}
}
$.ajax({
url: '#Url.Action("Upload", "Image")',
data: formData,
processData: false,
contentType: false,
type: "POST",
success: function () {}
errors: function () {}
});
});
This is one approach; taken from there:
$('#btnUpload').click(function () {
// Checking whether FormData is available in browser
if (window.FormData !== undefined) {
var fileUpload = $("#FileUpload1").get(0);
var files = fileUpload.files;
// Create FormData object
var fileData = new FormData();
// Looping over all files and add it to FormData object
for (var i = 0; i < files.length; i++) {
fileData.append(files[i].name, files[i]);
}
// Adding one more key to FormData object
fileData.append('username', ‘Manas’);
$.ajax({
url: '/Home/UploadFiles',
type: "POST",
contentType: false, // Not to set any content header
processData: false, // Not to process data
data: fileData,
success: function (result) {
alert(result);
},
error: function (err) {
alert(err.statusText);
}
});
} else {
alert("FormData is not supported.");
}
});
Another approach is to use the FileReader class to read the uploaded file, convert it to a base 64 string. Then you can send the base 64 string to the server.

C# web api / Javascript file upload set filename

I use asp.net web api for backend and a javascript client.
I use the form input to let the user select a file, and then I make an ajax request to the web api with the FormData, something like this:
var form = $('#uploadForm')[0];
var formData = new FormData(form);
$.ajax({
...
type: 'POST',
data: formData,
...
});
On the backend I receive this request, and get the data from the HttpContent object. Something like this:
try
{
if (!Request.Content.IsMimeMultipartContent("form-data"))
{
return StatusCode(HttpStatusCode.UnsupportedMediaType);
}
var result = await _blobRepository.UploadBlobs(Request.Content);
if (result != null && result.Count > 0)
{
return Ok(result);
}
return BadRequest();
}
I need to have unique file names.
How can I rename the file?
It does not matter if it is the client side, or the backend.

Minor trouble with AJAX POST method passing to C# MVC controller method

Hello denizens of stackoverflow, I've been debugging a pesky ajax POST method for a bit too long now, and was hoping I could get some input. I have a JavaScript function that collects an array of strings to box up and send off to a controller method of mine, but unfortunately the parameter data is not being sent, and I cannot figure out why.
Here is the JS function:
$.ajax({
url: 'CancelDoc',
method: 'POST',
datatype: 'json',
headers: addAntiForgeryHeader(),
data: { datakeys : DataKeys }
}).done(function (data) {
if (data.status == 0) {
alert("DOCUMENT CANCELLED SUCCESSFULLY");
}
});
To clarify a little:
DataKeys is the array of strings. It is coming through to this point as it should.
Looks something like:
["1432long-crazy4297-jumbled5826string|9000|1|1|NEW",
"1432and2-another03-jumbled1594string|9000|1|1|NEW"]
addAntiForgeryHeader() is an extra client validation method that I add on to all POSTs. The problem should not lie here because I have commented this out to try the call and it still does not pass data.
The C# controller method this goes to:
Note: the code DOES make it this far, the datakeys parameter is null though.
public ActionResult CancelDoc(string[] datakeys)
{
DocObject Doc = new DocObject();
List<string> Datakeys = datakeys.ToList();
foreach (var dk in Datakeys)
{
...
Some model logic here (not even making it here so no worries)
...
}
return Json(new { status = 0 });
}
I have tried:
Data conversion to JSON in numerous ways: ko.mapping.toJS(data), JSON.stringify(data), and literal writing of a JSON object for this.
Stripping the call down to the most basic form: I have tried commenting out the datatype and headers properties. This had a couple more properties before I posted as well.
Any input is greatly appreciated.
The dataKeys payload need to be stringify as :
$.ajax({
//prev code
data: { datakeys : JSON.stringify(DataKeys) }
}).done(function (data) {
//success
});
In the MVC controller, desearlze the json as:
public ActionResult CancelDoc(string[] datakeys)
{
dynamic sourceJson = JsonConvert.DeserializeObject(dataKeys, typeof(object));
DocObject Doc = new DocObject();
List<string> Datakeys = sourceJson.ToList();
}

Catching ajax file in ASP.Net MVC Controller

I want to upload file using ajax to an ASP.Net MVC Controller
My JavaScript code looks like this, basically every time the user changed the input value, it will automatically upload the file to the controller
var formdata = false;
if (window.FormData) {
formdata = new FormData();
}
$('input[name=default_export_filename]').change(function() {
var i = 0, len = this.files.length, img, reader, file;
for ( ; i < len; i++ ) {
file = this.files[i];
if (file.type.match(/spreadsheet/) || file.type.match(/ms-excel/)) {
if ( window.FileReader ) {
reader = new FileReader();
reader.onloadend = function (e) {
//showUploadedItem(e.target.result, file.fileName);
};
reader.readAsDataURL(file);
}
if (formdata) {
formdata.append("default_export_filename", file);
}
}
}
if (formdata) {
$.ajax({
url: root + mod + '/uploaddef',
type: "POST",
data: formdata,
processData: false,
contentType: false,
success: function (res) {
console.log(res);
}
});
}
});
In the controller side, I couldn't catch that file using this
[HttpPost]
public ActionResult UploadDEF(HttpPostedFileBase file)
{
var jsonData = new
{
response = 3
};
return Json(jsonData); ;
}
Or this
[HttpPost]
public ActionResult UploadDEF(FormCollectionfile)
{
var jsonData = new
{
response = 3
};
return Json(jsonData); ;
}
The file argument is always null. But in the firebug, I can see that the browser is posting the file to the server. With what object should I catch the file?
I realize the FormData object is not supported in older browser, but my clients are all using the latest browser. So that is not a problem.
The problem is solved.
It turns out I don't have to give any parameters to the controller's method. The files are available through Request object.
Thanks all
You can't use ajax POST to upload a file like this, must be a form submit.
Have a look at component like AjaxUploadify or similar.

MVC 3 jquery ajax post 2 objects

I have a controller action that takes two objects as arguments. I can't get it to work at all they always come back as null. My latest try looks like below. I have tried many other variations. In this case the FormInfo class is a class with 2 properties that are types for Form1 and Form2. I have also tried having the controller take in the two classes as arguments and the data part looked like { form1: form1Data, form2: form2Data } that was not working as well. I also tried using JSON.stringify to form the data with no luck.
Looking in the network monitor I see the data going back to the server it's just the engine that MVC uses to decode the query string to the objects can't handle what I'm passing back.
Thanks in advance for any information!
ClientSide
var formData = $("#form1").serialize();
var formData2 = $("#form2").serialize();
var formInfo = new Object();
formInfo.FormData = formData;
formInfo.FormData2 = formData2;
$.ajax({
url: 'Controller/Action',
type: 'POST',
data: formInfo,
success: function (data) {
//do stuff
}
});
ServerSide
public ActionResult SaveForms(FormInfo formInfo)
{
//Do Stuff here
}
You could use the a JSON request in conjunction with the .serializeArray() jQuery method. Let's suppose that you have the following model:
public class FormInfo
{
public Form1Data Form1Data { get; set; }
public Form2Data Form2Data { get; set; }
}
where Form1Data and Form2Data are some completely arbitrary complex classes. Now on the client we suppose that you have 2 distinct forms (#form1 and #form2 whose input element names match your complex structures in terms of default model binder wire format). Sending an AJAX request and packing the 2 forms together becomes trivial:
var form1Data = {};
$.each($('#form1').serializeArray(), function () {
form1Data[this.name] = this.value;
});
var form2Data = {};
$.each($('#form2').serializeArray(), function () {
form2Data[this.name] = this.value;
});
$.ajax({
url: '#Url.Action("someaction", "somecontroller")',
type: 'post',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({
form1Data: form1Data,
form2Data: form2Data
}),
success: function (result) {
// TODO: do something with the result
}
});
And of course the controller action you are POSTing to looks like this:
[HttpPost]
public ActionResult SomeAction(FormInfo formInfo)
{
...
}
I am doing something like this but i have a object and other Formdata to pass my Controller
var discrepancy = self.newCptyReply();
if ($('#UploadFile')[0]) {
var upload = new FormData(),
file = $('#UploadFile')[0].files[0];
upload.append('id', self.globalMessageId());
upload.append('discrepancy', ko.toJSON(discrepancy));
upload.append('doc', file);
}
datacontext.saveCptyToReply(self, upload);
And in controller signature
public ActionResult SaveCptyToReply(Guid id, Trade discrepancy, HttpPostedFileBase doc)
But when it reaches Controller id , doc are ok but discrepancy is null... It has data when funciton is called..
What to do...

Categories

Resources