Introduction
When you use the Ajax call in ASP.NET MVC, you can just return a JSON object but not a file. If you want to do that, you need to create and save the file in server and return its path to Ajax.
After that, you can call a redirect link for downloading the file, because this is a temp file, so you should need to delete it after download.
Using the Code
The below demo code is just for creating and downloading an Excel file:
- Create an Action for generating the Excel:
[HttpPost]
public JsonResult ExportExcel()
{
DataTable dt = DataService.GetData();
var fileName = "Excel_" + DateTime.Now.ToString("yyyyMMddHHmm") + ".xls";
string fullPath = Path.Combine(Server.MapPath("~/temp"), fileName);
using (var exportData = new MemoryStream())
{
Utility.WriteDataTableToExcel(dt, ".xls", exportData);
FileStream file = new FileStream(fullPath, FileMode.Create, FileAccess.Write);
exportData.WriteTo(file);
file.Close();
}
var errorMessage = "you can return the errors in here!";
return Json(new { fileName = fileName, errorMessage = "" });
}
- Create the download Action:
[HttpGet]
[DeleteFileAttribute]
public ActionResult Download(string file)
{
string fullPath = Path.Combine(Server.MapPath("~/temp"), file);
return File(fullPath, "application/vnd.ms-excel", file);
}
- We need to auto delete the file after download, so we need to create an Action Filter:
public class DeleteFileAttribute : ActionFilterAttribute
{
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
filterContext.HttpContext.Response.Flush();
string filePath = (filterContext.Result as FilePathResult).FileName;
System.IO.File.Delete(filePath);
}
}
- Use the Ajax call in frontend:
$.blockUI({ message: '<h3>Please wait a moment...</h3>' });
$.ajax({
type: "POST",
url: '@Url.Action("ExportExcel","YourController")',
contentType: "application/json; charset=utf-8",
dataType: "json",
}).done(function (data) {
$.unblockUI();
if (data.fileName != "") {
window.location.href = "@Url.RouteUrl(new
{ Controller = "YourController", Action = "Download"})/?file=" + data.fileName;
}
});