Download file using ajax - c#

I have a submit button on a form, when it's pressed the form is submitted and an Excel file is created on the server harddrive (C:/ExcelFiles).
After this has been done (after de form is submitted) I want to download this file using Ajax.
This is what I've done but it's not working:
$(document).on('click', '#saveButton', function () {
$('#saveMessage').empty();
$('#saveMessage').append("<p>Your file has been stored in C:\\ExcelFiles</p>");
var data = $('#fileName').val();
alert(data);
$.ajax({
type: 'POST',
url: '/Calculation/Download',
data: data,
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (returnValue) {
window.location = '/Calculation/Download?fileName=' + returnValue;
}
});
});
And my controller action look like this:
[HttpGet]
public virtual ActionResult Download(string fileName)
{
string fullPath = Path.Combine(Server.MapPath("~/ExcelFiles"), fileName);
return File(fullPath, "application/vnd.ms-excel", fileName);
}
Right now nothing happens. What am I doing wrong?

You cannot download files from the server by .ajax (due to security reasons).
You can however point the browser to that location and download the file.
The solution should be something like this:
$(document).on('click', '#saveButton', function () {
$('#saveMessage').empty();
$('#saveMessage').append("<p>Your file has been stored in C:\\ExcelFiles</p>");
var data = $('#fileName').val();
window.location = '/Calculation/Download?fileName=' + data ;
});

Related

Ajax request not hitting the right Post Method in Controller Class

I have a controller which contains two Post method, But whenever I make ajax request it is taking me to the first post method in the controller, instead I want to go to the second one, how do I route it to the second Post method?
This is the code I have so far, It works fine but only takes me to the first POST method, I am not sure on how to use my url in ajax ( may be that is causing the problem).
var ajax = Ext.Ajax.request({
url: './../ImportCSVFile',
data: details,
method: 'POST',
headers: { 'accept': '*/*' },
success: function (response, options) {
var result = JSON.parse(response.responseText);
if (mask) {
mask.destroy();
}
Ext.Msg.alert("File Upload Successful");
}
});
And here is my method in the controller that I want to reach:
[HttpPost]
public IActionResult ImportCSVFile(IFormFile formFile)
{
//sample of import file
}
415 means request is not in expected format. Pull up network tools in browser and see what request is being made and see whether its in the format that can reach ImportCSVFile controller Action or not.
with the details that you posted here this is what I came up with:
try this:
var ajax = Ext.Ajax.request({
url: './../ImportCSVFile',
data: JSON.stringify(details),
method: 'POST',
contentType: "application/json; charset=utf-8",
dataType: "json",
headers: { 'accept': '*/*' },
success: function (response, options) {
var result = JSON.parse(response.responseText);
if (mask) {
mask.destroy();
}
Ext.Msg.alert("File Upload Successful");
}
});
If you are using Razor syntax than you should use Url.Action method
var ajax = Ext.Ajax.request({
url: '#Url.Action("ImportCSVFile","ControllerNameHere")',
data: details,
method: 'POST',
headers: { 'accept': '*/*' },
success: function (response, options) {
var result = JSON.parse(response.responseText);
if (mask) {
mask.destroy();
}
Ext.Msg.alert("File Upload Successful");
}
});
Also if you could paste the controller that would be helpful.
EDIT: The issue is with the file that you are submitting with Ajax. It doesnt appear to be a url issue.
submission of file using jquery can be done like this
var fdata = new FormData();
//Get file here.
var fileInput = $('#File')[0];
var file = fileInput.files[0];
fdata.append("File", file);
// all other data here
$("input[type='text'").each(function (x, y) {
fdata.append($(y).attr("name"), $(y).val());
});
// or you can do something like this
f.data.append('Name' ,"valueofName")'
$.ajax({
type: 'post',
url: '../../ImportCSVFile',
data: fdata,
processData: false,
contentType: false
}).done(function(result) {
// do something with the result now
console.log(result);
});
Or probably something like this using Ext.Ajax
var file = s.fileInputEl.dom.files[0],
data = new FormData();
data.append('file', file);
Ext.Ajax.request({
url: '/upload/files',
rawData: data,
headers: {'Content-Type':null}, //to use content type of FormData
success: function(response){
}
});
Sample referred from here: File upload in extjs 4.2 without form.submit()

Pass parameter from Jquery to webhandler asp.net c#

I want to be able to drag and drop files into multiple folders on a server, I am using jquery to pass to HttpHandler but I can't pass the save location to webhandler. I would like to send the path from jquery in the request is there a way to incluse that when the data for file transfer is passed.
$.ajax({
type: "POST",
url: "FileHandler.ashx",
contentType: false,
processData: false,
data: data,
success: function (result) {
alert(result);
},
error: function () {
alert("There was error uploading files!");
}
});
Maybe something like this:
$.ajax({
type: "POST",
url: "FileHandler.ashx",
contentType: false,
processData: false,
data: data,
filepath: document.getElementById("<%=listDrop.ClientID%>");
success: function (result) {
alert(result);
},
error: function () {
alert("There was error uploading files!");
}
});
and then retrieve the path in the webhandler to pass as save location?
I have tried this $.ajax({
type: "POST",
url: "FileHandler.ashx",
contentType:false,
processData: false,
data: {
data: newData,
filepath:JSON.stringify("~/uploads/")
},
success: function (result) {
alert('success');
},
error: function () {
alert("There was error uploading files!");
}
}); But I have question about the declaration of the data type for the files I will be uploading when creating the get and set in asp. filepath is a string but what data type are the files.
although i am answering from my mobile, i tried my best to keep the things intact and use ful. If required, Please format it accordingly.
I am not going to write entire code here, just algo.
1. Identify the parameter to be passed. If its only path of multiple folders then you can create an array of objects in javascript for the same. See tge example
var listOfFolder = new string[];
listOfFolder[0]="path of first dir";
:
:
listOfFolder[n]="path of nth dir";
var data = JSON.stringify(listOfFolder);
2. pass this data in data attribute of jquery ajax. 3. Grab this path in Process Request event and deserialize.
4. Do whatever you want.

"Incorrect Content-Type: image/png" when trying to upload png with Ajax to Asp.net Core server

Hi I'm trying to upload arbitrary files with Ajax to my Asp.net Core server using the following code:
$.ajax({
url: '/Provider/Image/' + guid,
type: "POST",
contentType: false, // Not to set any content header
processData: false, // Not to process data
data: image,
success: function (result) {
alert(result);
},
error: function (err) {
alert(err.statusText);
}
});
where image is from a form with an input in it of type "file"
My C# is:
[ActionName("Image")]
[HttpPost]
[Authorize]
public async Task<IActionResult> UploadImage(List<IFormFile> files, Guid id)
{
var file = Request.Form.Files[0];
The problem is that "files" is empty and "file" gives me the error "Incorrect Content-Type: image/png"
StackTrace [string]:" at Microsoft.AspNetCore.Http.Features.FormFeature.ReadForm()\r\n at Microsoft.AspNetCore.Http.Internal.DefaultHttpRequest.get_Form()"
I had this problem once and my solution was to bind the upload mechanism to a ViewModel. In this way I was able to upload a file to server with additional parameters (in your case the guid you're passing to the url).
To do this I first created a view model
public class UploadImageViewModel
{
public IFormFile file {get;set;}
public Guid uniqueId {get;set;}
}
and used this in my controller
public async Task<IActionResult> UploadImage(UploadImageViewModel model)
{
//Here I can access my file and my Guid
var file = model.file;
Guid id = model.uniqueId;
}
in my jquery calls I then passed a model instead of a single (or multiple) file:
var dataModel = new FormData();
dataModel.append('file', document.getElementById("YOUR-FILEUPLOAD-FIELD-ID").files[0]);
dataModel.append('uniqueId', guid);
$.ajax({
url: '/Provider/Image/' + guid,
type: "POST",
contentType: false, // Not to set any content header
processData: false, // Not to process data
data: image,
success: function (result) {
alert(result);
},
error: function (err) {
alert(err.statusText);
}
});

Upload file from client side with jquery ajax call never getting the file selected

I have read some post here related but any one could help me out so far, I'm now trying upload a file selected in a input file in client side, then calling a server method using jquery ajax call, please how I'm doing it:
Sever Side Method:
[WebMethod]public static void UploadDetailImageFromClient(string filename, string caption, string itemid, string inspid) {
HttpPostedFile file = HttpContext.Current.Request.Files["ContentPlaceHolder1_uploadBtn"]; if (file != null && file.ContentLength > 0) //See the id here include ContentPlaceHolder as I'm using a MasterPage, here is where I'm never getting the file, it comes NULL
{
string fname = Path.GetFileName(file.FileName);
if (!System.IO.File.Exists(Path.Combine("images/", fname))) {
file.SaveAs(HttpContext.Current.Server.MapPath(Path.Combine("images/", fname)));
}
}
}
Client Side:
<td><asp:FileUpload ID="uploadBtn" runat="server" accept=".png,.jpg,.jpeg,.gif"/></td>
This is the function I invoke to call the server method:
function uploadnewpicture() {
jQuery.ajax({
type: "POST",
url: "FormInspectionsMidPoint.aspx/UploadDetailImageFromClient",
contentType: "application/json; charset=utf-8",
data: JSON.stringify({ filename: filename, caption: caption, itemid: itemid, inspid: inspid }),
dataType: "json",
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
},
success: function (data) {
jQuery("#ContentPlaceHolder1_uploadBtn").val("");
jQuery("#ContentPlaceHolder1_txtImageDetailCaption").val("");
alert("Picture uploaded successfully");
}
});
}
Please note that I'm calling this javascript function from a input button on click event which is inside a jQuery dialog box. This is why I'm using an ajax call to keep the dialog box on as well as read the value in the input file from the client side as well. I am also using enctype="multipart/form-data" in the form.
I hope someone has had same scenario and can help me. Thanks.
I have faced the Same Situation in my project. You can create a form data object in client side and add the file object to that form data object and pass to the controller. And receive the selected file from request in server side.
Client Side:-
var data = new FormData();
data.append("file", file);
Server Side:-
HttpPostedFileBase file = Request.Files["file"]

Request URL Too Long

I getting this error "Request URL Too Long" when i tried to download the file. The url shows the data that i want to download but it doesn't download.
How can i solve Request URL Too Long error when downloading
my code
Javascript
<script>
function DownloadIndexController(possID) {
$.ajax({
url: '#Url.Action("DownloadIndex", "Poss")',
contentType: 'application/json; charset=utf-8',
datatype: 'json',
data: { possID: possID },
type: "GET",
success: function (returnValue) {
window.location = '/DownloadIndex/Poss' + returnValue;
}
})
}
</script>
Controller
[HttpGet]
public virtual ActionResult DownloadIndex(int possID)
{
try
{
possFilename = possFilename.Replace(",", ",");
string fullPath = Filelocation + possFilename;
return File(fullPath, System.Net.Mime.MediaTypeNames.Application.Octet, possFilename);
}
catch (Exception ex)
{
throw ex;
}
You cannot use ajax to download a file in that way.
What you need to do is to generate a normal download link for every item in your grid, like:
#Html.ActionLink("Download", "DownloadIndex", "Home", new { possID = "123" }, null)
Where Home is the name of your controller, and you have to dynamically add the possID for every item instead of the hard coded 123 in my example.
In your code, you download the file using ajax, and then you redirect to an url containing the full file just after '/DownloadIndex/Poss'
You probably just want to redirect to the file, without using Ajax at all :
<script>
function DownloadIndexController(possID) {
window.location = '/DownloadIndex/Poss?possID=' + possID;
}
</script>

Categories

Resources