Unable to post files using ajax post - asp.net-mvc

We use ASP.Net Mvc 4.0.
My objecctive is to save a form with both normal input fields as well as file input fields.
I should be able to add extra data while posting.
I should be able to do perform few actions on 'Ajax Post's Success.
We used ajax post to post the form data as we could accomplish above 2, but failed in serializing and posting of files to server.
Whenever we post using ajax post, always Request.Files.Count == 0, when i check in my controller's Post Action.
ajax post i have used is:
function PostData(formId, eventSource, eventName, eventArgs, controlId) {
var $dialogForm = $("#" + formId + "Form");
fdata = $dialogForm.serialize();
fdata = fdata + '&eventSource=' + eventSource + "&eventName=" + eventName + '&eventArgs=' + eventArgs;
$.ajax({
url: $dialogForm.attr("action"),
type: $dialogForm.attr("method"),
cache: false,
data: fdata,
success: function (result) {
ProcessEvent(result);
}
});
}
Please provide me a solution for this!

well you cannot upload files when you go with the concept of ajax. But there are tweaks which are used to upload file and form data using ajax. Whenever a file type is encountered in a form the form data along with file can be copied to an iframe and the iframe can be submitted which give you a feel that file has been uploaded along with other form data using ajax.
There are various plugin available in jquery which ease this task for you.
One of my favourite is ajax form
http://malsup.com/jquery/form/#file-upload
You can use this one..

Related

Rails Frontend Trying to save autogenerated data to database without form

I'm new to ruby on rails. I'm trying to save data that is generated by itself to the database. i have looked into and found I was meant to use ajax, however all the videos/forums i have seen are example of ajax that use form and not refreshing page. i want to save data automatically without pressing submit.
Assume that the project is fresh project with postgresql as the database. I have created a database that can hold geo points by using postgis. i have created another page where it has map implemented where i can manully pin location. I want to save the manuuly pinned location to the database.
function onMapClick(e) {
alert("You clicked the map at " + e.latlng);
}
mymap.on('click', onMapClick);
var popup = L.popup();
function onMapClick(e) {
popup
.setLatLng(e.latlng)
.setContent("You clicked the map at " + e.latlng.toString())
.openOn(mymap);
}
mymap.on('click', onMapClick);
The e.latlng holds the geopoint, but i dont know how to save it the database if the user clicks anywhere on the map.
You don't need submit form to use ajax.
Basically what you want is add event listener to the map, and when user click then send ajax request to the controller.
For example, let's say that your map is inside div with id my-map.
If you use jQuery you can write something like this:
$('#my-map').on('click', function() {
# add your logic here
$.ajax({
url: 'your-url',
type: 'POST',
dataType: 'json',
contentType: "application/json; charset=utf-8",
data: JSON.stringify({
'let': data you want to send to backend
})
}
Hope it works!
EDIT:
After I looked your code I found that you can not have jQuery in your project so you can not use jQuery ajax. You need use vanilla javascript. So instead this snippet above, you can write this.
var xhttp = new XMLHttpRequest();
const params = { saving_location: { geoPoints: e.latlng } }
xhttp.onreadystatechange = function() {//Call a function when the state changes.
if(xhttp.readyState == 4 && xhttp.status == 200) {
alert(http.responseText);
}
}
xhttp.open("POST", "/saving_locations", true);
xhttp.setRequestHeader('Content-Type', 'application/json', 'Accept', 'application/json');
xhttp.send(JSON.stringify(params));
Also add protect_from_forgery with: :null_session in your application controller and skip_before_action :verify_authenticity_token in your Saving Location controller.(under before_action).
Here is good blog post why you need this https://blog.nvisium.com/understanding-protectfromforgery
Please notice that you wan't save your database, because your geoPoints type in database is type of point and you send string to rails controller. I never work with points in rails so I can not help you here.(You can always add two columns in db, one for longitude and one for latitude and then store numbers instead point)

File download feature in grails application

I am looking to create a file on the fly and offer a download link to the user in a GRAILS application.
I followed the approach from here. I have no errors however it doesn't seem to work. Here's my controller code.
`render (file: pptFile, fileName:'someppt.pptx', contentType: 'application/octet-stream')
Client side code makes an AJAX call to retrieve the file from server. It does not cause the server to force downloading of the file on the client (browser). Here's the client side code.
$.ajax({
type : 'POST',
url : '<<URL>>',
success: function(result) {
var uri = 'data:application/octet-stream;charset=UTF-8,' +
encodeURIComponent(result);
window.open(uri, 'somePPT.pptx');
},
failure: function(){
alert ('failure')
}
});
Perhaps something akin to this (paraphrased, but used for downloading a json file):
def someControllerMethod() {
def dlContent = someService.marshalJson()
def contentType = "application/octet-stream"
def filename = "someFilename.json"
response.setHeader("Content-Disposition", "attachment;filename=${filename}")
render(contentType: contentType, text: dlContent as JSON)
}
okay. So I finally got this to work. As proposed by #railsdog and many others (This problem has been discussed on other threads in stackoverflow but the specific case I had was slightly different from those) I ended up writing to response directly from server and took out the AJAX call. The only reason I was doing an AJAX call was because I did not want to submit the current page that had the "generate file" functionality (There are many data elements on the page and I did not want to re-do the entire page just for downloading the file). So I ended up using an anchor tag with target as "_blank". Here's the code snippet
<a href="myControllerMethodToGenerateFileAndWriteToHTTPResponseDirectlyAsSuggestedByOthersInThisPost"
target="_blank"/>
This actually opened a new page and did the submission to initiate the download. Problem solved. It's working fine in CHROME. :) Thanks guys!
I like the solution using the render method from #railsdog !
A slightly other approach which I used so far was:
def controllerMethod() {
...
File file = sepaXmlService.createTransfersFile(...)
response.setContentType("application/xml")
response.setHeader("Content-disposition", "attachment;filename=${file.getName()}")
OutputStream out = response.getOutputStream()
out.write(file.bytes)
out.close()
file.delete()
return
...
}
In the view I use the following statement in the form:
<g:actionSubmit action="controllerMethod" class="btn" value="Get XML!" /></td>
I think it should also be possible to use a
<g:link controller="foobar" action="controllerMethod" class="btn">GetXML</g:link>

c# MVC best way to make use of AJAX

In terms of making a an AJAX call, we have use the following method:
$.ajax({
type: "POST",
async: false,
url: '#Url.Action("CheckPhone", "Progg")',
data: { input: WebPhoneNum
},
success: function (iReturn) {
if (iReturn == 0) {
alert(Phone Number must be in format (XXX) XXX-XXXX. Please Re-Enter');
submitval = false;
}
},
error: function (xhr, status, error) {
var err = eval("(" + xhr.responseText + ")"); // Boil the ASP.NET AJAX error down to JSON.
alert('Call to CheckPhone failed with error: ' + err.Message); // display the error raised by the server
}
});
Notice how it makes a call to the controller and returns a value. I was wondering if there was a better way of doing this. I know .NET MVC has some ajax calls built in but couldn't find one that fits what I am doing below. I know .NET MVC has a ajax call build that with a hyperlink but that is not what I need. I just need to make a call to the controller that returns some value(s).
THanks
There's only one thing that you need to fix:
async: false
must become:
async: true
because otherwise you are not doing AJAX. You are sending a synchronous request to the server freezing the client browser.
Other than that you seem to be doing some remote validation with this AJAX request. You probably might take a look at the [Remote] attribute that's built in and which avoids you writing all this code. All you need to do is decorate the view model property that needs to be validated with this attribute and then enable unobtrusive client side validation by including the proper scripts.
try to validate the format of a input with ajax?
I recommend you learn about data annotations to validate that kind of details (please revalidate on server at submit form like a good practice)
here is a usefull tutorial http://www.asp.net/mvc/tutorials/older-versions/models-(data)/validation-with-the-data-annotation-validators-cs

File upload struts 2 with Ajax

I am uploading a file using struts 2 with jsp as front end, but I dont want to refresh the page after the file is uploaded, so i am using Ajax but with that I am not able to get the File object in action, it seems file upload needs form tag in jsp,and if I am submitting the form then the page gets refreshed.
I researched through the net but cant get many relevant results, it would be of great help if someone guides me through this, is there a way for it. Any help would really be appreciated.
Best regards
I suggest to use iframe for upload file instead of ajax,
Sample code for Upload Csv file using struts2 and iframe :
var file = $("#fileUpload").val();
if(file.indexOf(".") != -1 && file.substr(file.indexOf("."))==".csv"){
/* created IFrame For UPload file*/
var iframe = $('<iframe name="uploadIPAddressIFrame" id="uploadIPAddressIFrame" style="display: none" />');
$("body").append(iframe);
/* Set Form for submit iframe*/
var form = $('#ipPoolForm');
form.attr("action", "uploadCSVFile.do");
form.attr("target", "uploadIPAddressIFrame");
form.submit();
openDialog(title);
/* handle response of iframe */
$("#uploadIPAddressIFrame").load(function () {
response = $("#uploadIPAddressIFrame")[0].contentWindow.document.body.innerHTML;
$("#chkIPAddressDiv").html(response);
$("iframe#uploadIPAddressIFrame").remove();
});
After upload if you submit form then change target of form :
// Because of using iframe for upload set target value
$("#ipPoolForm").attr("target", "");

Client side processing in asp.net mvc 2.0

We are looking on an implementation in which data is processed at client side. Need inputs on how to process the data in JSON or any other type at client side in ASP.Net MVC 2.0.
Details: Inputs are accepted from the user and required to be saved in a list (or any other object) at the client side. Once the user actions are complete, the list object is required to be posted back to the server.
This is to avoid round trip to server and once all the data is ready in the list(objects) send it to server for processing
e.g. Accept Item(object) details as item name and item description. For first time add; in the same page store item in the list of object in client side itself. Every time item added, it is saved in list. At the same time list item is displayed on the same page in table format. After adding all the items when user submit data, list of object is posted back.
How can we achieve this in ASP.Net MVC 2.0 in a load balanced environment?
Any pointers would be very helpful
what kind of a list are you refering to here? like a bunch of check boxes? and in what format do you want to send the data to your server?
If you're using a bunch of checkboxes just post that data from the form straight to your action. I would suggest you just keep them in an array in javascript or add the values separated by a char like '|' or a ',' in a hidden text field and separate the items on the server side.
ASP.NET MVC 2 ships with the jQuery library, which you could use to perform this rough example...
var dataItems = new Array();
function AddDataItem(myDataItem) {
dataItems[dataItems.length] = myDataItem;
}
function SendDataItems() {
var data = "{";
for (var i = 0; i < dataItems.length; i++) {
data += ' question' + i + ': "' + dataItems[i] + '",';
}
// Remove the trailing comma:
data = data.substring(0, data.length-1) + "}";
$.ajax({
type: 'POST',
url: 'YourPage.html',
data: data,
success: function(response) {
alert(response);
},
dataType: "json"
});
}

Resources