Reputation: 6740
I have filters on a page that filters the data tables.
And an independent button to export data as excel.
I have followed this example: Download Excel file via AJAX MVC
When the export button is clicked jQuery reads all the filter values and pass the result back to server as below:
$.ajax({
url: url,
type: 'POST',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
data: filterData
}).done(function (returnData) {
if (returnData.success) {
window.location = returnData.locationUrl;
}
});
On the server I have 2 actions
[HttpPost]
public ActionResult ExportTo(SearchVm searchVm)
{
var data = _service.GetSearchTerm(searchVm).Take(150).ToList();
string handle = Guid.NewGuid().ToString();
TempData[handle] = data;
var fileName = $"C-{handle}.xlsx";
var locationUrl = Url.Action("Download", new { fileGuid = handle, fileName });
var downloadUrl = Url.Action("Download");
return Json(new { success = true, locationUrl, guid = handle, downloadUrl }, JsonRequestBehavior.AllowGet);
}
[HttpGet]
public ActionResult Download(string fileGuid, string fileName)
{
if (TempData[fileGuid] != null)
{
var fileNameSafe = $"C-{fileGuid}.xlsx";
var data = TempData[fileGuid] as List<Company>;
using (MemoryStream ms = new MemoryStream())
{
GridViewExtension.WriteXlsx(GetGridSettings(fileNameSafe), data, ms);
MVCxSpreadsheet mySpreadsheet = new MVCxSpreadsheet();
ms.Position = 0;
mySpreadsheet.Open("myDoc", DocumentFormat.Xlsx, () =>
{
return ms;
});
byte[] result = mySpreadsheet.SaveCopy(DocumentFormat.Xlsx);
DocumentManager.CloseDocument("myDoc");
Response.Clear();
Response.ContentType = "application/force-download";
Response.AddHeader("content-disposition", $"attachment; filename={fileNameSafe}");
Response.BinaryWrite(result);
Response.End();
}
}
return new EmptyResult();
}
The code above works fine to download files on local machine. However, When I make it live on the server, Export button click directs the user to the URL instead of downloading the file.
I cannot figure out why this is happening. The App is hosted on the azure web service. The only difference I can see between local and production is that production has ssl.
Is there any limitation with window.location? Why it would force browser to download file on local machine but it would redirect user to link on the production?
I have checked chrome console and there is no error.
Any idea why?
Thanks,
Upvotes: 1
Views: 6785
Reputation: 1467
-Return the fileName and the fileGuid to your Ajax method and concatenating the action URL instead of creating it in the backend and then call download action.
-Change the returned data :
[HttpPost]
public ActionResult ExportTo(SearchVm searchVm)
{
var data = _service.GetSearchTerm(searchVm).Take(150).ToList();
var handle = Guid.NewGuid().ToString();
TempData[handle] = data;
var fileName = $"C-{handle}.xlsx";
/// var locationUrl = Url.Action("Download", new { fileGuid = handle, fileName });
// var downloadUrl = Url.Action("Download");
return Json(new { success = true, guid = handle, fileName=fileName }, JsonRequestBehavior.AllowGet);
}
-Change ajax done function :
$.ajax({
url: url,
type: 'POST',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
data: filterData
}).done(function (returnData) {
if (returnData.success)
{
window.open('/download/' +returnData.guid + '/' + returnData.fileName, '_blank', '');
}
});
Upvotes: 1