First thing you should know: you cannot directly return a file from an AJAX callback, even it uses Response
instance. However, you can return a string which contains file name, and store file contents as byte array inside TempData
or Session
:
[HttpPost]
public ActionResult ActionName(...)
{
byte[] bytes;
// other logic here
using (var ms = new MemoryStream())
{
TextWriter tw = new StreamWriter(ms);
tw.WriteLine("Line 1");
tw.WriteLine("Line 2");
tw.WriteLine("Line 3");
tw.Flush();
bytes = ms.ToArray();
}
TempData["bytes"] = bytes; // add this line
return Json(new { fileName = "YourFileName.txt" });
}
Next, handle success
part of AJAX call with window.location
or window.location.href
set to URL which points to action name which will download the file:
$.ajax({
type: 'POST',
url: '@Url.Action("ActionName", "ControllerName")',
data: ...,
success: function(result) {
window.location = '@Url.Action("DownloadFile", "ControllerName")' + '?fileName=' + result.fileName;
}
});
Finally, create a controller with HTTP GET method and use byte array previously stored inside TempData
/Session
to return FileResult
:
[HttpGet]
public FileResult DownloadFile(string fileName)
{
if (TempData["bytes"] != null)
{
var content = TempData["bytes"] as byte[];
return File(content, "application/octet-stream", fileName);
}
else
{
return new EmptyResult();
}
}
If you're doing all of those in correct way, the text file should be able to download.